//  Open Social JavaScript wrapper, version 0.1
//  (c) 2007 Chris Chabot
//
//  This class is freely distributable under the terms of an MIT-style license.
//  For details, see the project's website:
//  http://www.chabotc.com/generic/second-step-into-the-open-social-world/

// This class can be used in 2 ways, either Extend this class to impliment functionality,
// and define the any following functions to hook up to the specific events your interested in:
// 	onInitialize(); called when the class initializes
// 	onLoading();    called when the request.send call has been made and the data is being loaded
// 	onComplete();   called when the person data has been loaded and parse
// 	onError(msg);	called when an error occured in the opensocial communication

// or call the class with onInitialize, onError, onLoading and/or onComplete functions in the options, for example:
// new osClass({ viewer:true, owner:true, onLoading: my_loading_function, onComplete: my_complete_function, onError: my_error_func});

// to access the social people data you can use the following json arrays:
// 	.owner
// 	.viewer
// 	.ownerFriends
// 	.viewerFriends
// owner and viewer are single items, where *Friends are array's
// each person entry is defined as:
// 	person.id       (string, unique consistent person id)
// 	person.name     (display name on the social site)
// 	person.isOwner  (bool, is this the owner of the page?)
// 	person.isViewer (bool, is this the viewer of the page?)
// 	person.profile  (string, url to the profile page of this person)
// 	person.thumb    (string, url to the thumbnail image)

// Usage: to retrieve only the viewer:
// 	new osClass({viewer:true});
// To retrieve everything (viewer, owner, & friends):
// 	new osClass({viewer:true,owner:true,viewerFriends:true,ownerFriends:true});

// other functions:
// hasError();		returns true when an error has occured
// getError();		returns the error message, or false if no error occured


var osClass = Class.create();
osClass.prototype = {
	viewer        : null,
	owner         : null,
	viewerFriends : null,
	ownerFriends  : null,
	error         : false,

	initialize: function() {
		// set options
		this.options        = Object.extend({
			viewer:         false,
			viewerFriends:  false,
			owner:          false,
			ownerFriends:   false,
			onInitialize:	false,
			onLoading:		false,
			onComplete:		false,
			onError:        false
		}, arguments[0] || {});
		// call onInitialize event hooks
		if (this.onInitialize != undefined)	this.onInitialize();
		if (this.options.onInitialize)      this.options.onInitialize();
		// if no data is requested, don't instance the opensocial object, no need
		if (this.options.viewer || this.options.owner || this.options.viewerFriends || this.options.ownerFriends) {
			var request = opensocial.newDataRequest();
		}
		// set data entries to retrieve: owner, viewer, and owner friends and viewer friends
		if (this.options.viewer)        request.add(request.newFetchPersonRequest("VIEWER"), "viewer");
		if (this.options.viewerFriends) request.add(request.newFetchPeopleRequest("viewerFriends"), "viewerFriends");
		if (this.options.viewer)        request.add(request.newFetchPersonRequest("OWNER"), "owner");
		if (this.options.viewerFriends) request.add(request.newFetchPeopleRequest("ownerFriends"), "ownerFriends");
		// only send request if any data has been requested
		if (this.options.viewer || this.options.owner || this.options.viewerFriends || this.options.ownerFriends) {
			request.send(this.initPeople.bind(this));
		}
		// call onLoading event hooks
		if (this.onLoading != undefined) this.onLoading();
		if (this.options.onLoading)      this.options.onLoading();
	},

	initPeople: function(response) {
		// parse the data requested into our own structure's (this.owner, this.viewer, this.ownerFriends and this.viewerFriends)
		if (response.hadError()) {
			this.error = 'global error from the server';
			if (this.options.onError) this.options.onError(this.error);
			if (this.onError)         this.onError(this.error);
			return;
		}
		if (this.options.viewer) {
			var viewer = response.get("viewer");
			if (viewer.hadError()) {
				this.error = 'Error in viewer object: '+viewer.getError();
				if (this.options.onError) this.options.onError(this.error);
				if (this.onError)         this.onError(this.error);
				return;
			}
			this.viewer = this.parsePerson(viewer.getData());
		}
		if (this.options.owner) {
			var owner   = response.get("owner");
			if (owner.hasError()) {
				this.error = 'Error in owner object: '+owner.getError();
				if (this.options.onError) this.options.onError(this.error);
				if (this.onError)         this.onError(this.error);
				return;
			}
			this.owner  = this.parsePerson(owner.getData());
		}
		if (this.options.viewerFriends) {
			var viewerFriends  = response.get("viewerFriends");
			if (viewerFriends.hasError()) {
				this.error = 'Error in viewerFriends object: '+viewerFriends.getError();
				if (this.options.onError) this.options.onError(this.error);
				if (this.onError)         this.onError(this.error);
				return;
			}
			this.viewerFriends = [];
			var viewerFriends = viewerFriends.getData();
			viewerFriends.each(function(person) {
				this.viewerFriends.push(this.parsePerson(person));
			}.bind(this));
		}
		if (this.options.ownerFriends) {
			var ownerFriends  = response.get("ownerFriends");
			if (ownerFriends.hasError()) {
				this.error = 'Error in ownerFriends object: '+ownerFriends.getError();
				if (this.options.onError) this.options.onError(this.error);
				if (this.onError)         this.onError(this.error);
				return;
			}
			this.ownerFriends = [];
			var ownerFriends = ownerFriends.getData();			ownerFriends.each(function(person) {
				this.ownerFriends.push(this.parsePerson(person));
			}.bind(this));
		}
		if (this.onComplete != undefined) this.onComplete();
		if (this.options.onComplete)      this.options.onComplete();
	},

	// map OpenSocial's Person object, to a straight self contained json array
	parsePerson: function(person) {
		return { 'id'       : person.getId(),
		'isOwner'  : person.isOwner(),
		'isViewer' : person.isViewer(),
		'name'     : person.getDisplayName(),
		'thumb'    : person.getField(opensocial.Person.Field.THUMBNAIL_URL),
		'profile'  : person.getField(opensocial.Person.Field.PROFILE_URL)
		};
	},

	hasError: function() {
		return this.error != false;
	},

	getError: function() {
		return this.error;
	}
}
