function initColorcubeOS()
{
	var self = new Object();
	self.activeRequest = false;

	self.getViewerHasApp = function(callback) {
		if (self.activeRequest)
			return false;
		
		self.activeRequest = true;
		var params = {};
		params[opensocial.DataRequest.PeopleRequestFields.FILTER] = opensocial.DataRequest.FilterType.HAS_APP;
		var dr = opensocial.newDataRequest();
		dr.add(dr.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER, params), "ViewerPerson");
		dr.send(dataLoaded);

		function dataLoaded(response) {
			var result = "0";
			if (!response.hadError()) {
				var viewer = response.get("ViewerPerson").getData();
				if (viewer) result = "1";
			}
			self.activeRequest = false;
			callback(result);
		}
	};

	self.getViewerOwnerRelation = function(callback) {
		if (self.activeRequest)
			return false;
		
		self.activeRequest = true;
		var relation = "0";
		var dr = opensocial.newDataRequest();
		dr.add(dr.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), "ViewerPerson");
		dr.send(viewerDataLoaded);
		
		function viewerDataLoaded(response) {
			if (!response.hadError()) {
				var viewer = response.get("ViewerPerson").getData();
				if (viewer.isOwner())
					relation = "1";
			}
			isViewerOwnerFriend();
		}
		
		function isViewerOwnerFriend() {
			var allFriends = {};
			//allFriends[opensocial.DataRequest.PeopleRequestFields.FIRST] = 1;
			allFriends[opensocial.DataRequest.PeopleRequestFields.MAX] = 999;
			var is = new opensocial.IdSpec();
			is[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.OWNER;
			is[opensocial.IdSpec.Field.GROUP_ID] = opensocial.IdSpec.GroupId.FRIENDS;
			var dr = opensocial.newDataRequest();
			dr.add(dr.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), "ViewerPerson");
			dr.add(dr.newFetchPeopleRequest(opensocial.newIdSpec(is), allFriends), "OwnerFriends");
			dr.send(dataLoaded);
		}
		
		function dataLoaded(response) {
			if (!response.hadError()) {
				var viewer = response.get("ViewerPerson").getData();
				var friends = response.get("OwnerFriends").getData();
				if (friends.getById(viewer.getId()))
					relation = "2";
			}
			self.activeRequest = false;
			callback(relation);
		}
	};

	self.getOwnerFriends = function(callback) {
		if (self.activeRequest)
			return false;
		
		self.activeRequest = true;
		var friendsWithApp = {};
		//friendsWithApp[opensocial.DataRequest.PeopleRequestFields.FIRST] = 1;
		friendsWithApp[opensocial.DataRequest.PeopleRequestFields.MAX] = 999;
		friendsWithApp[opensocial.DataRequest.PeopleRequestFields.FILTER] = opensocial.DataRequest.FilterType.HAS_APP;
		var is = new opensocial.IdSpec();
		is.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.OWNER);
		is.setField(opensocial.IdSpec.Field.GROUP_ID, opensocial.IdSpec.GroupId.FRIENDS);
		var dr = opensocial.newDataRequest();
		dr.add(dr.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER), "OwnerPerson");
		dr.add(dr.newFetchPeopleRequest(is, friendsWithApp), "OwnerFriends");
		dr.send(dataLoaded);
		
		function dataLoaded(response) {
			var object = new Array();
			if (!response.hadError()) {
				var owner = response.get("OwnerPerson").getData();
				var friends = response.get("OwnerFriends").getData();
				var id = owner.getId();
				if (id.indexOf('myspace') == 0) id = id.substr(12);
				object.push({'id':id, 'name':cleanString(owner.getDisplayName()), 'thumbnail':owner.getField(opensocial.Person.Field.THUMBNAIL_URL)});
				friends.each(function(person){
					var id = person.getId();
					if (id.indexOf('myspace') == 0) id = id.substr(12);
					object.push({'id':id, 'name':cleanString(person.getDisplayName()), 'thumbnail':person.getField(opensocial.Person.Field.THUMBNAIL_URL)});
				});
			}
			self.activeRequest = false;
			callback(object);
		}
	};

	self.getOwnerFriendsWithoutApp = function(callback) {
		if (self.activeRequest)
			return false;
		
		self.activeRequest = true;
		var friendsAll = {};
		//friendsAll[opensocial.DataRequest.PeopleRequestFields.FIRST] = 1;
		friendsAll[opensocial.DataRequest.PeopleRequestFields.MAX] = 999;
		var friendsWithApp = {};
		//friendsWithApp[opensocial.DataRequest.PeopleRequestFields.FIRST] = 1;
		friendsWithApp[opensocial.DataRequest.PeopleRequestFields.MAX] = 999;
		friendsWithApp[opensocial.DataRequest.PeopleRequestFields.FILTER] = opensocial.DataRequest.FilterType.HAS_APP;
		var is = new opensocial.IdSpec();
		is.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.OWNER);
		is.setField(opensocial.IdSpec.Field.GROUP_ID, opensocial.IdSpec.GroupId.FRIENDS);
		var dr = opensocial.newDataRequest();
		dr.add(dr.newFetchPeopleRequest(is, friendsAll), "OwnerFriendsAll");
		dr.add(dr.newFetchPeopleRequest(is, friendsWithApp), "OwnerFriendsWithApp");
		dr.send(dataLoaded);

		function dataLoaded(response) {
			var object = new Array();
			if (!response.hadError()) {
				var friendsAll = response.get("OwnerFriendsAll").getData();
				var friendsWithApp = response.get("OwnerFriendsWithApp").getData();
				friendsAll.each(function(person){
					if (!friendsWithApp.getById(person.getId())) {
						var id = person.getId();
						if (id.indexOf('myspace') == 0) id = id.substr(12);
						object.push({'id':id, 'name':cleanString(person.getDisplayName()), 'thumbnail':person.getField(opensocial.Person.Field.THUMBNAIL_URL)});
					}
				});
				self.activeRequest = false;
				callback(object);
			}
		}
	};

	self.getOwnerData = function(callback) {
		if (self.activeRequest)
			return false;
		
		self.activeRequest = true;
		var params = {};
		params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.GENDER,
																			opensocial.Person.Field.PROFILE_URL,
																			opensocial.Person.Field.CURRENT_LOCATION];
		var dr = opensocial.newDataRequest();
		dr.add(dr.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER, params), "OwnerPerson");
		dr.send(dataLoaded);

		function dataLoaded(response) {
			var object = null;
			if (!response.hadError()) {
				var person = response.get("OwnerPerson").getData();
				var id = person.getId();
				if (id.indexOf('myspace') == 0) id = id.substr(12);
				object = {'id':id, 'name':cleanString(person.getDisplayName())};
				var gender = person.getField(opensocial.Person.Field.GENDER);
				if (typeof(gender.getDisplayValue) == "function") object['gender'] = gender.getDisplayValue();
				else object['gender'] = gender;
				object['thumbnail'] = person.getField(opensocial.Person.Field.THUMBNAIL_URL);
				object['profile'] = person.getField(opensocial.Person.Field.PROFILE_URL);
				var location = person.getField(opensocial.Person.Field.CURRENT_LOCATION);
				if (location) {
					object['city'] = location.getField(opensocial.Address.Field.LOCALITY);
					object['state'] = location.getField(opensocial.Address.Field.REGION);
					object['country'] = location.getField(opensocial.Address.Field.COUNTRY);
				}
			}
			//for (var i in object) debug(i + " : " + object[i]);
			self.activeRequest = false;
			callback(object);
		}
	};

	self.createActivity = function(title, content, icon, callback) {
		if (self.activeRequest)
			return false;
		
		self.activeRequest = true;
		var params = {};
		params[opensocial.Activity.Field.TITLE] = title;
		params[opensocial.Activity.Field.BODY] = content;
		params[opensocial.Activity.Field.STREAM_FAVICON_URL] = icon;
		var activity = opensocial.newActivity(params);
		opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, dataLoaded);

		function dataLoaded(response) {
			var result = "0";
			if (!response.hadError()) {
				result = "1";
			}
			self.activeRequest = false;
			callback(result);
		}
	};

	self.createTemplateActivity = function(id, variables, media, callback) {
		if (self.activeRequest)
			return false;
		
		if (document.all)
			return false;
		
		self.activeRequest = true;
		var params = {};
		params[opensocial.Activity.Field.TITLE_ID] = id;
		params[opensocial.Activity.Field.TEMPLATE_PARAMS] = variables;
		params[opensocial.Activity.Field.MEDIA_ITEMS] = mountMedia(media);
		
		var activity = opensocial.newActivity(params);
		opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, dataLoaded);

		function dataLoaded(response) {
			//debug(response);
			//for (var i in response) debug(i + " : " + response[i]);
			var result = "0";
			if (!response.hadError()) {
				result = "1";
			}
			self.activeRequest = false;
			callback(result);
		}
	};

	self.createNotification = function(friends, message, callback) {
		if (self.activeRequest)
			return false;
		
		self.activeRequest = true;
		opensocial.requestShareApp(friends, opensocial.newMessage(message), dataLoaded);

		function dataLoaded(response) {
			var result = "0";
			if (!response.hadError()) {
				result = "1";
			}
			self.activeRequest = false;
			callback(result);
		}
	};
	
	self.createRandomNotification = function(message, callback) {
		if (self.activeRequest)
			return false;
		
		self.activeRequest = true;
		var friendsAll = {};
		//friendsAll[opensocial.DataRequest.PeopleRequestFields.FIRST] = 1;
		friendsAll[opensocial.DataRequest.PeopleRequestFields.MAX] = 999;
		var friendsWithApp = {};
		//friendsWithApp[opensocial.DataRequest.PeopleRequestFields.FIRST] = 1;
		friendsWithApp[opensocial.DataRequest.PeopleRequestFields.MAX] = 999;
		friendsWithApp[opensocial.DataRequest.PeopleRequestFields.FILTER] = opensocial.DataRequest.FilterType.HAS_APP;
		var is = new opensocial.IdSpec();
		is.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.OWNER);
		is.setField(opensocial.IdSpec.Field.GROUP_ID, opensocial.IdSpec.GroupId.FRIENDS);
		var dr = opensocial.newDataRequest();
		dr.add(dr.newFetchPeopleRequest(is, friendsAll), "OwnerFriendsAll");
		dr.add(dr.newFetchPeopleRequest(is, friendsWithApp), "OwnerFriendsWithApp");
		dr.send(dataLoaded);

		function dataLoaded(response) {
			if (!response.hadError()) {
				var fullIds = new Array();
				var friendsAll = response.get("OwnerFriendsAll").getData();
				var friendsWithApp = response.get("OwnerFriendsWithApp").getData();
				friendsAll.each(function(person){
					if (!friendsWithApp.getById(person.getId())) {
						fullIds.push(person.getId());
					}
				});
				var ids;
				if (fullIds.length <= 20) ids = fullIds;
				else {
					ids = new Array();
					var random;
					while(ids.length < 20) {
						random = Math.floor(Math.random()*fullIds.length);
						ids.push(fullIds[random]);
						fullIds.splice(random, 1);
					}
				}
				//for (var i in ids) debug(i + " : " + ids[i]);
				self.activeRequest = false;
				self.createNotification(ids, message, callback);
			}
			else {
				self.activeRequest = false;
				callback("0");
			}
		}
	};

	self.requestServer = function(url, callback, postdata) {
		var param = new Object();
		param[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
		param[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
		if (postdata) {
			param[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
			param[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
			param[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues(postdata);
			//url += "&owner_id=ID" + gadgets.util.getUrlParameters()["gadgetOwner"] + "ID";
			//for (var i in postdata) debug(i + " : " + postdata[i]);
		}
		gadgets.io.makeRequest(url, dataLoaded, param);
		
		function dataLoaded(response) {
			//for (var i in response) debug(i + " : " + response[i]);
			callback(response);
		}
	};

	return self;
}

function cleanString(string)
{
	//string = gadgets.util.unescapeString(string);
	string = string.replace(/'/g, '');
	string = string.replace(/"/g, '');
	//string = string.replace(/\\/g, '');
	return string;
}

function mountMedia(media)
{
	var mediaItems = [];
	for (var i in media) {
		mediaItems.push(opensocial.newMediaItem(media[i]["mime"], media[i]["url"]));
	}
	return mediaItems;
}