/*
 * Copyright 2009 Palm, Inc. All rights reserved.
 */
/*global Mojo, Class, $L, PalmSystem */
/*jslint rhino:true, undef:true */

function NetworkMonitor() 
{
	this.online = true;
    this.monitoring = false;
}

NetworkMonitor.prototype.startMonitoring = function() 
{
    if (this.monitoring) {
        return;
    }

    this.monitoring = 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) 
                {	
                    try 
                    {
                        self.online = response.isInternetConnectionAvailable;
                        if (self._userStatusChangeCb) 
                        {
                            self._userStatusChangeCb(response);
                        }
                    }
                    catch (e) 
                    {
                        Mojo.Log.logException(e);
                    }
                },
            onFailure: function() 
                {
                    Mojo.Log.error("Failure subscribing to connection mgr status");
                }
			});
	} 
    else 
    {
		if (PalmSystem.version.match("desktop")) 
        {
			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;
    this.startMonitoring();
};

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);
        }
    );

};
