var sai = {
    _turl: "sai",
    _lurl: "sai",
    _gui: "box",
    _sessionid: new Date().getTime() + "" + Math.floor(9000 * Math.random() + 1000),
    _sessionOptions: {},
    _onProcessingStart : null,
    _onProcessingFinish : null,
    _onError : function(request) { alert(request.getErrorMessage()); },
    _maxTranslatedWords : null,
    _asynchroneous: true,
    _cancelled: false,

    translateText: function(text, languagePair, onComplete) {
        return sai.sendRequest(text, languagePair, "translate", onComplete);
	},

    translateHtml: function(text, languagePair, onComplete) {
        return sai.sendRequest(text, languagePair, "urlmarkuptranslate", onComplete);
	},

    lookup: function(text, languagePair, onComplete, subService) {
        var options = {};
        options["gui"] = sai._gui;
        options["lp"] = languagePair;
        options["format"] = "html";
        return sai.sendGenericRequest(sai._lurl, "lookup" + (subService ? "_" + subService : ""), options, text, onComplete);
	},

    sendRequest: function(text, languagePair, service, onComplete) {
        var options = {};
        options["gui"] = sai._gui;
        options["lp"] = languagePair;
        if(window.richText)
            options["LEMMA_ALTMEANING"] = "1";
        if(sai._maxTranslatedWords)
            options["MAX_TRANSLATED_WORDS"] = sai._maxTranslatedWords;
        return sai.sendGenericRequest((service == "lookup" ? sai._lurl : sai._turl), service, options, text, onComplete);
    },

    sendGenericRequest: function(url, service, options, data, onComplete) {
        var xmlReq = null;
        if (window.XMLHttpRequest) {
            xmlReq = new XMLHttpRequest();
        }
        if (xmlReq == null) {
            try {
                xmlReq = new ActiveXObject("Msxml2.XMLHTTP"); //later IE
            } catch (e) {
                try {
                    xmlReq = new ActiveXObject("Microsoft.XMLHTTP"); //earlier IE
                } catch (e) {
                    xmlReq = null;
                }
            }
        }
        if (xmlReq == null) {
            alert ("Your browser does not support the XMLHttpRequest object.")
            return;
        }
        options["sessionid"] = sai._sessionid;
        var query = "?";
        if(sai._sessionOptions) {
            for(var name in sai._sessionOptions) {
                if(sai._sessionOptions.hasOwnProperty(name)) {
                    query += name + "=" + sai._sessionOptions[name] + "&";
                }
            }
        }
        for(var name in options) {
            if(options.hasOwnProperty(name)) {
                query += name + "=" + options[name] + "&";
            }
        }
        query += "service=" + service;
        xmlReq.open("POST", url + query, sai._asynchroneous);
        if(sai._onProcessingStart) {
            sai._onProcessingStart(request);
        }
        xmlReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
        xmlReq.setRequestHeader("Connection", "close");
        var request = new WebServiceRequest(xmlReq, service, onComplete);
        xmlReq.onreadystatechange = function() { sai.checkRequests(request); };
        xmlReq.send(data);
        return request;
    },

    checkRequests: function(request) {
        if(typeof(request) != "undefined" && request.isComplete()) {
            try {
                if(!request.isSuccess() && sai._onError) {
                    if (!request.isCancelled())
                        sai._onError(request);
                }
                request.onComplete();
                request.clean();
            }
            catch(ex) {}
            if(sai._onProcessingFinish) {
                sai._onProcessingFinish(request);
            }
        }
    }
};

function WebServiceRequest(xmlReq, resultType, onComplete) {
	this._xmlReq = xmlReq;
    this._parsedResponse = null;
    this._resultType = resultType;
    this._onComplete = onComplete;
    this._cancelled = false;

    this.isComplete = function() {
        return this._xmlReq == null || this._xmlReq.readyState == 4;
	};

	this.isSuccess = function() {
        if(this.isComplete()) {
            if(this._xmlReq == null || this._xmlReq.status == 200) {
                return this.getParsedResponse().error == "";
            }
        }
        return false;
	};

    this.isCancelled = function() {
        return this._cancelled;
    };

    this.getResultType = function() {
        return this._resultType;
    };

    this.getOutput = function () {
        return this.getParsedResponse().body;
	};

	this.getErrorMessage = function() {
        if(this._xmlReq == null || this._xmlReq.status == 200) {
            return this.getParsedResponse().error;
        }
        else {
            return "HTTP Error " + this._xmlReq.status + ": " + this._xmlReq.statusText;
        }
	};

	this.cancel = function() {
        this._cancelled = true;
        if(!this.isComplete()) {
            this._xmlReq.abort();
        }
    };

    this.getParsedResponse = function() {
        if(this._parsedResponse == null) {
            this._parsedResponse = new SAIResponse(this._xmlReq.responseText);
        }
        return this._parsedResponse;
    };

    this.onComplete = function() {
        if(this._onComplete) {
            this._onComplete(this);
        }
    };

    this.clean = function() {
        try {
            if ((typeof(this._xmlReq.close) != "undefined"))
                this._xmlReq.close();
        } catch(e) {
        }
        delete this._xmlReq;
        this._xmlReq = null;
        this._cancelled = false;

    };
}

function SAIResponse(txtResponse) {
    this.body = "";
    this.error = "";
    this.options = {};

    this._init = function(txtResponse) {
        var stIndex = 0;
        var eqIndex = 0;
        var nlIndex;

        while(stIndex < txtResponse.length && eqIndex != -1) {
            eqIndex = txtResponse.indexOf("=", stIndex);
            if (eqIndex != -1) {
                var optionName = txtResponse.substring(stIndex, eqIndex);
                if(optionName == "body") {
                    nlIndex = txtResponse.indexOf("\n", eqIndex);
                    this.body = txtResponse.substring(nlIndex + 1);
                    stIndex = txtResponse.length;
                }
                else {
                    nlIndex = txtResponse.indexOf("\n", eqIndex);
                    var optionValue = txtResponse.substring(eqIndex + 1, nlIndex);
                    this.options[optionName] = optionValue;
                    if(optionName == "error") {
                        this.error = optionValue;
                    }
                    stIndex = nlIndex + 1;
                }
            }
        }
    };

    this._init(txtResponse);
}

