//	SERVER-SIDE MODULE
//	(PLEASE DO NOT MODIFY THIS CODE)
//
//	The JS proxy to the King County Web Service (Locator_WS).
//
//	It exposes a set of verbs each which correspond to their server-side
//	equivalent. Some verbs include:
//
//	searchLocation ().
//
//	USAGE:
//	Pass the constructor an application-level object, whose callback functions
//	will be invoked to accept any responses from the web service.
//	The name of these callback functions are identical to the name of the
//	verb.
//
//	For example, consider SEARCH_LOCATIONS.
//
//	Your application code would look as follows:
//	var	ws = new Locator_WS (myAppObject);
//	ws.searchLocations (...);		<<- sends the SEARCH_STORE request
//	myAppObject.searchLocations (...)	<<- receives the SEARCH_STORE response
//
//	The interface is designed to be comfortable to a JS application developer
//	and is shielded from the low-level wire-protocol implementation mucky details.


//
//	PUBLIC
//

function Locator_WS (callbackObject)
{
try {
	this.callbackObject = callbackObject;
	this.ahc = new AsyncHttpConn (this.WEB_SERVICE_URL, this);

} catch (e) { alert ("Locator_WS (callbackObject) threw: " + e); }
}


Locator_WS.prototype.searchLocations = function (type, minLat, minLon, maxLat, maxLon, startDate, endDate, lang)
{
	this.currentRequest 	= 	"SEARCH_LOCATIONS";

	var				request =	"SEARCH_LOCATIONS\n" +
//								this.ROW_LIMIT + "\n" +
								type + '\n' +
								minLat + '\n' +
								minLon + '\n' +
								maxLat + '\n' +
								maxLon + '\n' +
								startDate + '\n' + 
								endDate + '\n' +
                                lang + '\n';
try {
	this.ahc.send (request, this.WEB_SERVICE_URL);
} catch (e) { alert ("searchLocations () caught: " + e); }
}

//
//	CALLBACK (PROTECTED)
//

//	Dispatches all responses from web service to the appropriate handler.

Locator_WS.prototype.ahcReply = function (message)
{
	try {

	var		lines = message.split ('\n');

	//	Remove the last line (which is empty).
	lines.pop ();

	//	Parse response
	var		message = lines[0];
    var     type = lines[1];
    var     locations = null;

	if (this.currentRequest == "SEARCH_LOCATIONS") {
		if (message == "OK") {
			locations = Locator_WS.readMultipleLocations (lines, type, 2);
		}

		try {
		this.callbackObject.searchLocations (message, type, locations);
		} catch (e) {
			alert ("searchLocations () client-side handler threw an exception: " + e);
		}
	}

	} catch (e) {
		//	Typically invoked if response format is corrupt.
		alert ("Caught exception calling dispatchResponse (): " + e);
	}
}


//
//	PRIVATE
//

Locator_WS.prototype.WEB_SERVICE_URL = "../servlet/Location_WS";


//
//	UTILITY FUNCTIONS
//

//	Reads multiple locations, and returns the locations as an
//	array. If no locations were read, an array of length 0 is returned.

Locator_WS.readMultipleLocations = function(lines, type, begin) {

	var				locations = [];

    // determine which parsing function to use
    var readLocation = null;
    var recordSize = 0;
    if (type == Locator_WS.OFFICE_TYPE) {
        readLocation = Locator_WS.readOffice;
        recordSize = Locator_WS.OFFICE_SIZE;
    }
    else if (type == Locator_WS.EVENT_TYPE) {
        readLocation = Locator_WS.readEvent;
        recordSize = Locator_WS.EVENT_SIZE;
    }
    else if (type == Locator_WS.ADVISORY_TYPE) {
        readLocation = Locator_WS.readAdvisory;
        recordSize = Locator_WS.ADVISORY_SIZE;
    }
    else {
        alert ("Bad location type returned from Web Service: " + type);
        return;
    }
    var	idx = begin;
	while (true) {
		var			loc = readLocation (lines, idx);

		if (loc == null) {
			break;
		}

		locations.push (loc);

		//	Advance to the next location
		idx += recordSize;
	}

	return locations;
}


//	Starting with 'lines[begin]' and continuing to 'lines[begin+13]' construct
//	and return a Locations object.
//	Return null if a fully formed location couldn't be read.

Locator_WS.readOffice = function(lines, begin) {
	//	ARE THERE ARE SUFFICIENT LINES TO READ ENTIRE CONTENTS OF LOCATION

	if (begin + Locator_WS.OFFICE_SIZE > lines.length) {
		return null;
	}

	var				loc = {};

	//	READ LOCATION

	try {
	    loc.type            = Number (lines[begin]);
		loc.lat 	    	= Number (lines[begin+1]);
		loc.lon 		    = Number (lines[begin+2]);
		loc.title   		= lines[begin+3];
		loc.address1    	= lines[begin+4];
		loc.address2	    = lines[begin+5];
		loc.city    		= lines[begin+6];
		loc.state	    	= lines[begin+7];
		loc.postal  		= lines[begin+8];
		loc.country		    = lines[begin+9];
		loc.phone	    	= lines[begin+10];
		loc.territory	    = lines[begin+11];
		loc.office_hours	= lines[begin+12];
		loc.time_diff   	= lines[begin+13];
		loc.fax         	= lines[begin+14];
		loc.email       	= lines[begin+15];
		loc.web         	= lines[begin+16];
		loc.holidays    	= lines[begin+17];
		loc.other_url   	= lines[begin+18];
		loc.office_id   	= lines[begin+19];
		loc.country_id   	= lines[begin+20];
		loc.region_id		= lines[begin+21];
		loc.has_multiple_offices = lines[begin+22];

	} catch (e) {
		loc = null;
	}

	return loc;
}

Locator_WS.readEvent = function(lines, begin) {

	//	ARE THERE ARE SUFFICIENT LINES TO READ ENTIRE CONTENTS OF LOCATION

	if (begin + Locator_WS.EVENT_SIZE > lines.length) {
		return null;
	}

	var				loc = {};

	//	READ LOCATION

	try {
    loc.type            = Number (lines[begin]);
	loc.lat 	    	= Number (lines[begin+1]);
	loc.lon 		    = Number (lines[begin+2]);
	loc.title   		= lines[begin+3];
	loc.country		    = lines[begin+4];
	loc.event_date  	= lines[begin+5];
	loc.time_diff    	= lines[begin+6];
	loc.url     	    = lines[begin+7];
	loc.event_location	= lines[begin+8];

	} catch (e) {
		loc = null;
	}

	return loc;
}

Locator_WS.readAdvisory = function(lines, begin) {

	//	ARE THERE ARE SUFFICIENT LINES TO READ ENTIRE CONTENTS OF LOCATION

	if (begin + Locator_WS.ADVISORY_SIZE > lines.length) {
		return null;
	}

	var				loc = {};

	//	READ LOCATION

	try {
    loc.type            = Number (lines[begin]);
	loc.country		    = lines[begin+1];
	loc.advisoryLevel	= Number(lines[begin+2]);
	loc.fromDate    	= lines[begin+3];
	loc.toDate	    	= lines[begin+4];
	loc.warning	    	= lines[begin+5];
	loc.description    	= lines[begin+6];
	loc.link	    	= lines[begin+7];

	} catch (e) {
		loc = null;
	}

	return loc;
}

Locator_WS.OFFICE_TYPE = 1;
Locator_WS.EVENT_TYPE = 2;
Locator_WS.ADVISORY_TYPE = 3;
Locator_WS.OFFICE_SIZE = 23;
Locator_WS.EVENT_SIZE = 9;
Locator_WS.ADVISORY_SIZE = 8;

