/**
 * Copyright 2003-2010 SearchFit, Inc. All rights reserved.
 * -------------------------------------------------------------
 * Permission to use, copy, modify, and distribute this
 * software for any purpose without permission is forbidden!
 * -------------------------------------------------------------
 * Analytics callback class which will initiate the analytics...
 */

var proxy_script = 'tool_proxy_ws.php';
 
function SearchFitAnalytics(url, id_user,use_proxy) {
    this.callback_url = url;
    this.get_vars = new Array();
    this.id_user = id_user;    
    this.use_proxy = use_proxy;
    this.setGetTags();
    var cookie_name = 'anna_tracking_'+id_user;
    this.get_vars['id_user']    = this.id_user;
    this.get_vars['__referer']  = document.referrer;
    this.get_vars['page_name']	= document.location.href;

    // remove the part after the hash if there is already a question mark
    var posQuestion = this.get_vars['page_name'].indexOf("?"); var posHash = this.get_vars['page_name'].indexOf("#");
    if (posQuestion != -1 && posHash != -1) { this.get_vars['page_name'] = this.get_vars['page_name'].substring(0, posQuestion); }

	var pos	= document.cookie.indexOf(cookie_name+"=");
	if (pos == -1) {
		this.execAjax(0);
	} else {
		var start = pos + cookie_name.length + 1;
		var end = document.cookie.indexOf(";", start);
		if (end == -1) { end = document.cookie; } 		
		this.execAjax(document.cookie.substring(start,end));
	}
};

SearchFitAnalytics.prototype = {
    callback_url: null,
    get_vars: null,

    // pass the current GET fields to the anna
    setGetTags: function() {
        var tmp = document.URL.split(/\?/);
        if (tmp.length <= 1) { return; }
        var get_tags = tmp[tmp.length - 1];
        var get_elements = get_tags.split(/\&/);
        for (var x = 0; x < get_elements.length; x++) {
            var ele = get_elements[x]; if (ele.indexOf("#") != -1) { continue; }
            var spl = ele.split(/\=/);
            this.get_vars[name] 
            var name = spl[0];
            var value = decodeURIComponent(spl[1]);
            value = value.replace(/\+/g, ' ');
            this.get_vars[name] = value;
        }
    },

	// convert the get array to a URI component
    convertGet:	function(get_arr) {
	    var fields = '';
	    for (key in get_arr) {        
	        var value = get_arr[key];
	        if (typeof(value) == 'undefined') { value = ''; }
	        if (fields != '') { fields += '&'; } 
	        if (!encodeURIComponent) { fields += escape(key) + '=' + escape(value); }
	        else { fields += encodeURIComponent(key) + '=' + encodeURIComponent(value); }  
	    } 
	    return fields;    
    },

    // execute indirectly by sending a request to the proxy script; this is when we don't have a tracking id
    execAjax: function(id_tracking) {
		var ajax = new AjaxConnection();
		var listener = this;
		ajax.errorHandler = function(err,aj) {} // ignore errors
		ajax.processer = function(root_node, aj) {
			var tracking = root_node.getElementsByTagName("Tracking").item(0);
			var id_tracking = tracking.attributes.getNamedItem("id").value;
			var cookie_name	= 'anna_tracking_'+listener.id_user;
			// set the cookie
			document.cookie = cookie_name + '=' + id_tracking;
		}

        var url = this.callback_url + '?' + this.convertGet(this.get_vars) + '&seed=' + escape((new Date).getTime());
        if (id_tracking > 0) { url += '&tracking=' + id_tracking; }

		if (this.use_proxy == true) {		
			ajax.Connect( proxy_script + "?targetEndpoint=" + escape(url) + '&action=track&wsParams=&xml=');
		} else {
			ajax.addPostVar('action','track');
			ajax.Connect(url);
		}
    },

    // execute directly by displaying the analytics image. BUG: this crashes IE7 on bad HTML =/
    displayImage: function(id_tracking) {
		var img;
	    if (document.createElementNS && document.body.namespaceURI) {
	        img = document.createElementNS(document.body.namespaceURI, 'html:img');
	    } else {
	        img = document.createElement('img');
	    }

	    img.style.display = 'none';
	    this.get_vars['tracking']	= id_tracking;
	    var fields = this.convertGet(this.get_vars);
	    if (fields != '') { img.src = this.callback_url + '?' + fields; } else { img.src = this.callback_url; }

	    document.body.appendChild(img);    
    }
};

// Ajax Connection and callback functions
function AjaxConnection() {
    this.http_request = null;
    this.processer = function (root_node, ajax) {};
    this.not_ready_callback = function(response_code, aj) { };
    this.errorHandler = function (text, aj) { alert(text); };
    this.errorTag = "Error";
    this.request_type = 'get';
    this.post_vars = new Array();
};

// AjaxConnection::addPostVar. Add a variable to post (if we are posting)
AjaxConnection.prototype.addPostVar = function(name, value) {
    this.post_vars[this.post_vars.length] = encodeURIComponent(name) + '=' + encodeURIComponent(value);
    this.request_type = 'post';
}
AjaxConnection.prototype.clearPost = function() {
    this.post_vars = new Array();
    this.request_type = 'get';
}

// AjaxConnection::CreateAjax. Create the XMLHttpRequest class, with the evil evil switch to see if IE supports it.
AjaxConnection.prototype.CreateAjax = function() {
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
    try {
        this.http_request = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
        try {
            this.http_request = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
            this.http_request = null;
        }
    }
    @end @*/

    if (!this.http_request && typeof XMLHttpRequest != 'undefined') { this.http_request = new XMLHttpRequest(); }
    if (!this.http_request) { this.errorHandler('Fatal Error: couldn\'t create AJAX request, old browser?, IE with ActiveX disabled?', this); return; }
    return this.http_request;
}

// AjaxConnection::Connect. Connect to the inputted URL
AjaxConnection.prototype.Connect = function(url) {
    this.CreateAjax();
    if (this.http_request) {
        var listener = this;
        this.http_request.onreadystatechange = function() { listener.readyChange(); };
        this.http_request.open(this.request_type.toUpperCase(), url, true);
        if (this.request_type.toLowerCase() == 'post') {
            this.http_request.setRequestHeader('Content-Type', "application/x-www-form-urlencoded; charset=UTF-8");
            this.http_request.send(this.post_vars.join('&'));
        } else {
            this.http_request.send(null);
        }    
    }
}

// AjaxConnection::handleEvent. Handles the onreadystatechange event
AjaxConnection.prototype.readyChange = function() {
    if (!this.http_request) { alert("request is still false"); return; }

    if (this.http_request.readyState == 4) {
        if (this.http_request.status == 200 || (this.http_request.status >= 500 && this.http_request.status <= 599) ) {
            var xmldoc = this.http_request.responseXML;            
            var root_node;

            if (!xmldoc || !xmldoc.firstChild) {
        		if (this.http_request.status != 200) {
		            this.errorHandler("Error connecting to Ajax, Reason: HTTP/" + this.http_request.status, this);
        		} else {
	                this.errorHandler("Failed parsing XML Document", this);
                }
                return;
            }

            // this works in mozilla, need to find the IE version
            root_node = xmldoc.firstChild;
            if (root_node.nodeName == "parsererror") {
                this.errorHandler(root_node.nodeName + "\n\n" + this.http_request.responseText, this);
                return;
            }

            // okay lets find out who we are supposed to contact
            root_node = xmldoc.documentElement;
            this.root_node = root_node;
            if (!this.checkBtsAjaxError(root_node)) { return; }
            this.processer(root_node, this); 
        } else {
            this.errorHandler("Error connecting to Ajax, Reason: HTTP/" + this.http_request.status, this);
        }
    } else {
        this.not_ready_callback(this.http_request.readyState, this);
    }    
}

// AjaxConnection::checkBtsAjaxError. Checks and sees if there has been an error in the processing of the command
AjaxConnection.prototype.checkBtsAjaxError = function(root_node) {
    if (!root_node) { this.errorHandler("Root Node Is Not Defined", this); return false; }
    var error = root_node.getElementsByTagName(this.errorTag).item(0);
    if (error && error.nodeName == this.errorTag) {
        if (error.firstChild) {
            this.errorHandler(error.firstChild.nodeValue, this);
        } else {
            this.errorHandler('error was sent by the ajax processor, but had no content', this);
        }
        return false;
    }
    return true;
}