// 
//  NetworkMonitor.js
//  browser
//  
//  Copyright 2008-2009 Palm, Inc. All rights reserved.
//
function NetworkMonitor() {
	
	// Always assume true and let the system tell us otherwise.
	this.online = true;
	
	// We need to listen on connection manager state
	this._connMgrService = new Mojo.Service.Request('palm://com.palm.bus/signal', {
		method: 'registerServerStatus',
		parameters: {
			'serviceName':'com.palm.connectionmanager'
		},
		onSuccess: this._connectionManagerSignal.bind(this)
	});
	
}

NetworkMonitor.prototype._connectionManagerSignal = function(payload) {
	
	if (payload.connected) {
		Mojo.Log.info("@@@ CONNECTION MANAGER SIGNAL - UP");
		// On a signal we re-subscribe to the connection manager.
		var self = this;
		this.connMgrSubscription = new Mojo.Service.Request('palm://com.palm.connectionmanager', {
				method: 'getstatus',
				parameters: {'subscribe': true},
				onSuccess: function(response) {	
					
					self.online = response.isInternetConnectionAvailable;
					if (self._userStatusChangeCb) {
						self._userStatusChangeCb(response);
					}
				},
				onFailure: function() {
					Mojo.Log.error("Failure subscribing to connection mgr status");
				}
			});
					
	} else {
		if (PalmSystem.version.match("desktop")) {
			// No connection manager AND we are the desktop so assume
			// we are running untethered
			Mojo.Log.info("@@@ CONNECTION MANAGER SIGNAL - DOWN - BUT ASSUMING RUNNING ON THE DESKTOP");
			this.online = true;
		} else {
			Mojo.Log.info("@@@ CONNECTION MANAGER SIGNAL - DOWN");
			this.online = false;
			this.stopObserving();
		}
	}
};

NetworkMonitor.prototype.observe = function(statusChangeCb) {
	
	this._userStatusChangeCb = statusChangeCb;
};

NetworkMonitor.prototype.stopObserving = function() {
	if (this.connMgrSubscription) {
		this.connMgrSubscription.cancel();
		delete this.connMgrSubscription;
	}
};

NetworkMonitor.prototype.addNetworkCheckedMethods = function(params) {
	
	params = params || {};
	var prefix = "_netchecked_";
	var that = params.target;
	var onNetworkDown = params.onNetworkDown;
	var monitor = this;
	var methods = params.methods || [];
	methods.each(function(method) {
		
		that[prefix+method] = that[method];
		that[method] = function(m) {
			
			var self = that;
			return function() {

				if (monitor.online) {					
					self[prefix+m].apply(self, arguments);
				} else {
					if (onNetworkDown) {
						onNetworkDown({
							method: m,
							args: arguments
						});
					}
				}				
			};
		}(method);
	});
};
