/* Auto-Bus Widget City File For Phenix Arizona US
 * Version 1.0.0
 * March 22nd 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 Phenix
 * 
 * Line Number: enter the line you want to monitor.
 * Note that this version only supports numbered lines (eg. 17)
 * or numbered lines folowed by a letter (eg. 3A) but NOT lines that
 * are identified by a name (eg. Red Line).
 * 
 * Stop column number: This is the number of the colunm
 * that represents your bus stop on the timetable web page at
 * http://www.valleymetro.org/bus/Bus_Routes/.
 * Start counting from 1. Example: Route 1 Eastbound, for the
 * stop on Central at Van Buren, enter 3
 * 
 * Display Texts: optional, but help identify the stops when
 * monitoring several simultaneously. If the direction display
 * text field is left empty, the direction specified in the
 * drop down menu will be used.
 */

//-----------------------------------------------------------------------

/* 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();

	// Do not modify above this line
	//------------------------------
	// Start of city specific code
	
	url.location = "http://www.valleymetro.org/bus/Bus_Routes/Route_" + this.args[0] + ".htm";
	
	// 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,
		temp,
		now;
	
	now = new Date();
	if (now.getDay() == 0) {
		temp = "Sunday ";
	} else if (now.getDay() == 6) {
		temp = "Saturday ";
	} else {
		temp = "Monday-Friday ";
	}
	temp += this.args[2] + "bound Schedule";
	str = this.data;
	passageTimes = [];
	str = str.substr(str.indexOf(temp));
	for (i = 0,k = 0; i < 5 && k < 200; k++) {
		str = str.substring(str.indexOf("<tr align"));
		for(j = 0; j < parseInt(this.args[1]); j++) {
			str = str.substr(str.indexOf("ptp") + 7);
		}
		if(str.substring(0,1) == "<"){
			str = str.substring(str.indexOf(">")+1);
		}
		time = convertTime(str.substring(0, str.indexOf("<")));
		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 = new Array();
	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 = "popup";
	formFields[i].option = ["North","South","East","West"];
	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 at http://www.valleymetro.org/bus/Bus_Routes/. Start counting from 1. Example: Route 1 Eastbound, for the stop on Central at Van Buren, 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" );
	
	if( formResults != null ){
		
		var args = [];
		args[0] = formResults[0];
		args[1] = formResults[2];
		args[2] = formResults[1];
		args[7] = formResults[3];
		if (formResults[4] != "") {
			args[8] = formResults[4];
		} else {
			args[8] = formResults[1];
		}
		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 = new Array();
	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 = "popup";
	formFields[i].option = ["North","South","East","West"];
	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 at http://www.valleymetro.org/bus/Bus_Routes/. Start counting from 1. Example: Route 1 Eastbound, for the stop on Central at Van Buren, 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" );
	
	if( formResults != null ){
		var args = [];
		STOPS[busStop].args[0] = formResults[0];
		STOPS[busStop].args[1] = formResults[2];
		STOPS[busStop].args[2] = formResults[1];
		STOPS[busStop].args[7] = formResults[3];
		if (formResults[4] != "") {
			STOPS[busStop].args[8] = formResults[4];
		} else {
			STOPS[busStop].args[8] = formResults[1];
		}		
		// 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.
 */

function convertTime(str){
	print(str);
	var time = new Date();
	if (str.indexOf("a") > 0){
		time.setMinutes(str.substr(str.indexOf("a")-2,2));
		time.setHours(str.substring(0,str.indexOf("a")-2));
	} else {
		time.setMinutes(str.substr(str.indexOf("p")-2,2));
		hr = parseInt(str.substring(0,str.indexOf("p")-2));
		if(hr < 12){
			time.setHours(hr+12);
		} else {
			time.setHours(hr);
		}
	}
	return time;
}



