/*
File:	mops.js
This file is used to define the classes and objects that are used to define MOPS 
entities

Section:	Version History
03/06/2009 (DJO) - Created File
*/

// define the MOPS global namespace
var MOPS = {};

// define a container for the mops regions info
MOPS.regions = {};

// define the MOPS loader
MOPS.loader = {
	// define the REST queries for getting data
	YQL: {
	    SRCDB: "http://mops-australia.dabbledb.com/publish/mops-australia/641fae17-7719-4c97-95ab-25867522e1ca/allgroups.rss",
		GETGROUPS_FORZONE:	"http://query.yahooapis.com/v1/public/yql?q=select%20*%20%0Afrom%20feed%20%0Awhere%20url%3D'{dburl}'%0Aand%20zone%20%3D%20'{zone}'&format=json&callback=?",
		
		/*
		Method: getZoneUrl
		This method is used to get the url of the zone for the specified zoneid
		*/
		getZoneUrl: function(zoneId) {
            // initialise the function result
            var fnresult = MOPS.loader.YQL.GETGROUPS_FORZONE.replace("{zone}", zoneId);
            
            // now set the database source
            fnresult = fnresult.replace("{dburl}", escape(MOPS.loader.YQL.SRCDB));
		
		    // return the zone url
		    return fnresult;
		}
	},
	
	loadZone: function(zone, callback) {
		jQuery.status.push("Finding MOPS groups for " + zone.title);			
	
		// execute the query to locate the data from yahoo
		jQuery.getJSON(MOPS.loader.YQL.getZoneUrl(zone.id), function(data) {
			for (var ii = 0; data.query.results && (ii < data.query.results.item.length); ii++) {
				zone.addGroup(data.query.results.item[ii]);
			} // for
			
			jQuery.status.pop();	
			
			// if we have results now, then call the goto state method again
			jQuery.feedback.log("found " + zone.groups.length + " groups for zone: " + zone.title);
			if (zone.groups.length > 0) { 
				MOPS.groupfinder.gotoZone(zone.id); 
			} // if
			
			// flag the zone as loaded
			zone.loaded = true;			
			
			// if a callback is defined, then call the callback
			if (callback) {
				callback(zone.groups);
			} // if
		});	
	} // getGroupsForZone
}; // MOPS.loader

MOPS.Group = function(groupTitle) {
	// initialise private variables
	var CONST_ATTR_ADDRESS = 'meetingaddress';
	var CONST_ATTR_MEETINGDAY = 'meetingday';
	var CONST_ATTR_MEETINGREG = 'meetingregularity';
	var CONST_ATTR_MEETINGTIME = 'meetingtime';
	var CONST_ATTR_PHONE = 'phone';
	var CONST_ATTR_EMAIL = 'contactemail';
	var CONST_HTML_GROUPDETAILS = "<div class='groupinfo'><h4>{title}</h4><p class='groupaddress'>{address}</p><p class='meetingtime'>{meetingtime}</p><ul class='groupcontact'>{contact}</ul></div>";
	
	// initialise defaults
	var DEFAULT_HTMLOPTS = {
		searchLink: false
	}; // DEFAULT_HTMLOPTS

	return {
		// define some attribute values
		title: groupTitle,
		latlng: null,
		mapPin: null,
		address: '',
		meetingTime: '',
		phone: '',
		email: '',
		
		/*
		Method:	asHtml
		This method is used to return the mops data as html
		*/
		asHtml: function(opts) {
			var settings = jQuery.extend(this.DEFAULT_HTMLOPTS, opts ? opts : {});		
			
			// initialise the contact details
			var contactHtml = this.phone ? "<li class='contactphone'>" + this.phone + "</li>" : "";
			
			// add the email contact details
			contactHtml += this.email ? "<li class='contactemail'>" + this.email + "</li>" : "";
		
			return CONST_HTML_GROUPDETAILS.
						replace("{title}", this.title).
						replace("{address}", this.address.replace(/\,/g, "<br />") + 
							(settings.searchLink ? "<p class='search'><a target='_blank' href='" + this.getSearchLink() + "'>Search for Location</a></p>" : "")).
						replace("{contact}", contactHtml).
						replace("{meetingtime}", this.meetingTime);										
		}, // asHtml
		
		/*
		Method:	getSearchLink
		This method is used to get the search link for the specified address
		*/
		getSearchLink: function() {
			return "http://maps.google.com/maps?q=" + escape(this.address);
		}, // getSearchLink
		
		locate: function() {
			// save a reference to self
			var group = this;
		
			// locate the address
			MOPS.groupfinder.locateAddress(group.address, { callback: function(point) {
				// update the group latlong
				group.latlng = point;						
			
				// pin the location 
				group.mapPin = MOPS.groupfinder.pinMap(group.latlng, group.title, group.asHtml(), false, false);
				
				// add an event listener for the pin
				google.maps.Event.addListener(group.mapPin, "click", function() {
					group.mapPin.openInfoWindowHtml(group.asHtml());
				});
			}});
		}, // locate
		
		parseData: function(data) {
			// iterate through the group data and copy it to the object
			for (var keyName in data) {
				// if the item is not already defined, then copy it across
				if (! this[keyName]) {
					this[keyName] = data[keyName];
				}
				else {
					// alert("could not copy " + keyName + " attribute");
				} // if..else
			} // for
			
			// if we have the address attribute set, then update the address and clear the latlng
			if (this[CONST_ATTR_ADDRESS]) {
				this.address = this[CONST_ATTR_ADDRESS];
				this.latlng = null;
				this.mapPin = null;
			} // if
			
			// parse the meeting time
			this.meetingTime = '';
			if (this[CONST_ATTR_MEETINGDAY]) {
				this.meetingTime += this[CONST_ATTR_MEETINGDAY];
			} // if
			
			if (this[CONST_ATTR_MEETINGREG]) {
				this.meetingTime += " " + this[CONST_ATTR_MEETINGREG];
			} // if
			
			if (this[CONST_ATTR_MEETINGTIME]) {
				this.meetingTime += ": " + this[CONST_ATTR_MEETINGTIME];
			} // if
			
			if (this[CONST_ATTR_PHONE]) {
			    this.phone = this[CONST_ATTR_PHONE];
			} // if
			
			if (this[CONST_ATTR_EMAIL]) {
			    this.email = this[CONST_ATTR_EMAIL];
			} // if
		} // parseData
	}; 
}; // MOPS.Group

/*
Class:	Group
This class is used to define the methods that are used to define a mops group
*/
MOPS.Zone = function (zoneId, title, bounds) {
		// initialise the attribute mappings
		var attributeMappings = {
			
		}; // 

		return {
			// publicly accessible attributes
			id: zoneId,
			title: title,
			bounds: bounds,	
			groups: [],	
			loaded: false,
		
			/*
			Method:		addGroup
			This method is used add some group data to the state
			*/
			addGroup: function(groupData) {
				var group = new MOPS.Group(groupData.groupname);
				
				// get the group to parse the data
				group.parseData(groupData);
				
				// then add the group to the list
				this.groups.push(group);
			} // addGroup
		}; 
};

/* define some utility functions */

MOPS.getGroup = function(groupKey) {
	// initialise result
	var fnresult = null;

	// split the key on the - character
	var keys = groupKey.split("-");
	
	// the keys need to be 3 long for us to locate
	if (keys.length >= 3) {
		// find the region
		var region = this.regions[keys[0]];
		
		// if the region is defined, then continue
		if (region) {
			var zone = region.zones[keys[1]];
			
			// if we found the zone, then continue
			if (zone && (zone.groups.length >= keys[2])) {
				fnresult = zone.groups[keys[2]];
			} // if 
		} // if
	} // if		
	
	return fnresult;
}; // getGroup 

