/* Copyright 2009 Palm, Inc.  All rights reserved. */

Weave.Services.ConnectionManager =
{
	_target: 'palm://com.palm.connectionmanager',
	_online: undefined,
	_1x: undefined,
	_waiting: [],
	_started: false,
	
	_startup: function(callback)
	{
		this._started = true;
		if (PalmSystem.version.match("desktop")) 
		{
			// Simulator is always online
			this._stateChanged(true);
			callback && callback(this._online);
			callback = null;
		}
		else 
		{
			var self = this;
			
			// register for entering msm notifications
		 	this._MSMrequest = Weave.Services.request('palm://com.palm.bus/signal',
			{
				method: 'addmatch',
				parameters:
				{
					"category" : "/storaged",
					"method" : "MSMProgress",
					"subscribe" : true
				}
			},
			function(response)
			{
				self._MSMnotification(response);
			},
			function(response)
			{
				Mojo.Log.error("ConnectionManager._startup MSM subscription request failed %j", response);
				self._MSMnotification(response);
			});
	
			this._getstatusreq = Weave.Services.request(this._target, 
			{
				method: 'getstatus',
				parameters: 
				{
					subscribe: true
				},
			},
			function(response)
			{
				Mojo.Log.info ("ConnectionManager.connectionStatusNotification %j", response);
				self._1x = response.wan.network == "1x" && response.wifi.state != "connected";
				self._stateChanged((response.isInternetConnectionAvailable == true ? true : false));
				callback && callback(self._online);
				// callback = null;
			},
			function()
			{
				self._stateChanged(false);
				callback && callback(self._online);
				// callback = null;
			});
		}
	},
	
	_MSMnotification: function(response) 
	{	
		if (!response) return;
	
		Mojo.Log.info ("ConnectionManager._MSMnotification %j", response);
		if (response.stage == 'attempting') 
		{
			Mojo.Log.info ("ConnectionManager._MSMnotification: in MSM");
			this._MSMmodeActive = true;
			ConnectionWidget.cancel();
		}
	},

	_stateChanged: function(online)
	{
		if (this._online != online)
		{
			this._online = online;
			var waiting = this._waiting;
			this._waiting = [];
			for (var i = 0; i < waiting.length; i++) 
			{
				var wait = waiting[i];
				if (wait.online === undefined || wait.online === online) 
				{
					waiting[i].callback(online);
				}
				else
				{
					this._waiting.push(wait);
				}
			}
		}
		
		if (online == false)
		{
			this.showConnectionError();
		}
		else 
		{
			// if internet is available we are certainly not in MSM mode
			this._MSMmodeActive = false;
			ConnectionWidget.cancel();
		}
	},
	
	/*
	 * Enable monitoring of network status.
	 */
	monitor: function()
	{
		if (!this._started) 
		{
			this._startup();
		}
	},
	
	getStatus: function(callback)
	{
		if (this._online === undefined) 
		{
			if (!this._started) 
			{
				this._startup(callback);
			}
			else
			{
				this._waiting.push({ online: undefined, callback: callback });
			}
		}
		else 
		{
			callback(this._online);
		}
	},
	
	isOnline: function()
	{
		if (this._online === undefined)
		{
			throw new Error("ConnectionManager is not monitoring status");
		}
		else
		{
			return this._online;
		}
	},
	
	isOn1x: function()
	{
		return this._1x;
	},
	
	waitForOnline: function(callback)
	{
		if (this._online === true)
		{
			callback();
			return undefined;
		}
		else
		{
			var wait = { online: true, callback: callback };
			this._waiting.push(wait);
			return wait;
		}
	},
	
	waitForOffline: function(callback)
	{
		if (this._online === false)
		{
			callback();
			return undefined;
		}
		else
		{
			var wait = { online: false, callback: callback };
			this._waiting.push(wait);
			return wait;
		}
	},
	
	cancelWait: function(wait)
	{
		var waiting = this._waiting;
		for (var i = 0; i < waiting.length; i++)
		{
			if (waiting[i] == wait)
			{
				waiting.splice(i, 1);
				break;
			}
		}
	},
	
	showConnectionError: function() 
	{
		// don't show connection widget if we are in MSM mode
		if (this._MSMmodeActive) return;
		
		var stage = Weave.System.Activator.getActiveStageController();
		if (!stage) return;
		
		if (!stage.isActiveAndHasScenes()) return;
			
		Mojo.Log.info("ConnectionManager.showConnectionError");
		var params = 
		{
			type: "data",
			onSuccess: function(response){}
		};
		ConnectionWidget.connect(params, stage);
	},
	
	cleanup: function()
	{
		// close connection's widget stage if active
		ConnectionWidget.cancel();
		delete this._MSMrequest;
		delete this._getstatusreq;
	}
	
};