/*
 * Copyright (c) 2006-2007 Collactive. All rights reserved.
 */
if (typeof(Collactive) == 'undefined') {
	Collactive = {};
}

Collactive.CSAUtils = {
	hasCSA: function() {
		if (this._hasCSA == null) {
			if (navigator.appName.indexOf("Microsoft") != -1) {
				this._hasCSA = this.ieCheckCSA();
			}
		}
		return this._hasCSA;
	},

	isCSAEngineVersionSatisfactory: function(config) {
		var requiredVersion = null;
		if (navigator.appName.indexOf("Microsoft") != -1) {
			requiredVersion = this._parseVersion(config.ieMinVersion);
		} else {
			requiredVersion = this._parseVersion(config.firefoxMinVersion);
		}

		var version = [-1, -1, -1, -1];
		if (typeof(Collactive.CSAUtils.getWindow().actionScriptEngineVersion) != "undefined") {
			version = this._parseVersion(Collactive.CSAUtils.getWindow().actionScriptEngineVersion);
		} else if (navigator.appName.indexOf("Microsoft") != -1) {
			// In IE we can check this explicitly.
			try {
				var obj = new ActiveXObject("CollactiveWebAssistant.AssistantControl");
				var version_str = obj.version();
				version = this._parseVersion(obj.version());
				if (this._compareVersions(requiredVersion, version) > 0) {
					// Special case: during upgrade we need to explicitly request the new version.
					try {
						var obj = new ActiveXObject("CollactiveWebAssistant.AssistantControl." + config.ieCodebaseVersion);
						var version_str = obj.version();
						// Since in IE we'll still get the older ActiveX (but getting this far means that we have the
						// newer version), we fool it.
						version = requiredVersion;
					} catch (e) {
					}
				}

			} catch (e) {
			}
		} else {
			// Assume FF version 1.1.0.5
			version = [1, 1, 0, 5];
		}

		return this._compareVersions(requiredVersion, version) <= 0;
	},

    mapPaths: {},

    defineMapPaths: function(paths) {
        this.mapPaths = paths;
    },

	map: function(name, includeList, excludeList, scriptsList) {
	    var currentTime = (new Date()).getTime() / 1000;
        var host = "" + document.location.host;
		var scripts = [];
		for (var i = 0; i < scriptsList.length; ++i) {
		    var scriptPath = scriptsList[i];
		    var definedPath = this.mapPaths[scriptPath];
		    if (definedPath != null) {
    		    scriptPath = definedPath;
    		}
    		if (scriptPath.match(/^http/)) {
    	        scripts.push(scriptPath);
       		} else {
          		scripts.push("http://" + host + scriptPath);
		    }
		}
		if (this._api) {
			this._api.setScriptMapping(name, includeList, excludeList, scripts);
		}
	},

	clearMapping: function() {
		this._api.clearScriptMapping.call();
	},

	disableStaticMapping: function() {
	    if (this._api.disableStaticMapping) {
    		this._api.disableStaticMapping.call();
	    }
	},

    getWindow: function() {
    	if (typeof(unsafeWindow) != 'undefined') {
    		return unsafeWindow;
    	} else {
    		return window;
    	}
    },

	init: function(callback) {
		this._userCallback = callback;
		if (this.getWindow().actionScriptAPI && this.getWindow().actionScriptVersion) {
			this._api = this.getWindow().actionScriptAPI;
			this._api.clearScriptMapping.call();
			this._api.registerCallback(Collactive.bind(this, this._callback));
		}
	},

	waitForAPIReady: function(callback) {
		if (this.getWindow().actionScriptAPI && this.getWindow().actionScriptVersion) {
			this._api = this.getWindow().actionScriptAPI;
		}
		if (this._api) {
		    callback();
		} else {
		    this._waitForAPIReady = callback;
		}
	},

	getVersion: function() {
		return this.getWindow().actionScriptVersion;
	},

	// Called from the SA - are we actually using the CSA?
	isCSA: function() {
		return (typeof(CAScriptEngine) != 'undefined' && !Collactive.ProxyUtils.isProxy());
	},

	_callback: function() {
		var args = [];
		for (var i = 0; i < arguments.length; ++i) {
			args.push(arguments[i]);
		}
		if (this._userCallback) {
			this._userCallback.apply({}, args);
		}
	},

	ieCheckCSA: function() {
		try {
			var obj = new ActiveXObject("CollactiveWebAssistant.AssistantControl");
			if (obj.version()) {
				return true;
			}
		} catch (e) {
		}
		return false;
	},

    _parseVersion: function(str) {
		if (str == null) {
            return [ -1, -1, -1, -1 ];
		}
        var l = str.split('.');
        if (l.length != 4) {
            return [ -1, -1, -1, -1 ];
        }
        for (var i = 0; i < l.length; ++i) {
            l[i] = parseInt(l[i]);
            if (isNaN(l[i])) {
                return [ -1, -1, -1, -1 ];
            }
        }
        return l;
    },

	// returns: -1 if a < b, 0 if a == b, 1 if a > b
    _compareVersions: function(a, b) {
        if (a.length != 4 || b.length != 4) {
            throw "Bad version information";
        }
        for (var i = 0; i < a.length; ++i) {
            if (a[i] < b[i]) {
				return -1;
			} else if (a[i] > b[i]) {
				return 1;
			}
        }
        return 0;
    },


	notifyOperation: function(operationName) {
	   if (typeof(notifyOperation) != "undefined") {
	       notifyOperation(operationName);
	   }
	}
};

if (!Collactive.CSAUtils.isCSA()) {
	Collactive.CSAUtils.getWindow().actionScriptReady = function() {
		var self = Collactive.CSAUtils;
		self._hasCSA = true;
		self._api = self.getWindow().actionScriptAPI;
		self._api.registerCallback(Collactive.bind(self, self._callback));
		if (self._waitForAPIReady) {
			self._waitForAPIReady();
		}
	};

	Collactive.DomUtils.registerListener(window, 'unload', function() {
		Collactive.CSAUtils.getWindow().actionScriptReady = null;
		if (Collactive.CSAUtils._api) {
			Collactive.CSAUtils._api.clearScriptMapping();
			Collactive.CSAUtils._api.registerCallback(null);
		}
	});
}