/** ECMAScript / Javascript
 * @file resources/js/yRemote.js
 */

var yRemote = Class.create({
    initialize: function() {
        this.xmlRequest = null;
        this.currentTimeout = null;
        this.aborted = false;
        this.useJson = true;
    },
    getTransport: function() {
        return Try.these(
            function() { return new XMLHttpRequest() },
            function() { return new ActiveXObject('Msxml2.XMLHTTP') },
            function() { return new ActiveXObject('Microsoft.XMLHTTP') }
            ) || false;
    },
    reset: function() {
        if ((this.xmlRequest = this.getTransport()) === false)
            return false;
        this.aborted = false;
        this.currentTimeout = null;
        return true;
    },
    abort: function() {
        this.aborted = true;
        if (this.currentTimeout)
        {
            clearTimeout(this.currentTimeout);
            this.currentTimeout = null;
        }
    },
    onStateChange: function () {
        if (this.aborted) return;
        switch (this.xmlRequest.readyState) {
          case 3:        // receiving
            this.onLoading();
            break;
          case 4:        // loaded
            this._onLoad();
            break;
          case 0:        // uninitialized
          case 1:        // open
          case 2:        // sent
          default:
            // we don't care
        }
    },
    // WARNING: timeout delay is NOW in seconds instead of miliseconds
    get: function(url, timeout) {
        if (!this.reset())
            return false;
        if (timeout !== undefined)
            this.currentTimeout = setTimeout(this._onTimeout.bind(this), timeout*1000); //setTimeout is in milliseconds
            // TODO: REMOVE THIS -> QUICK FIX MADE TO REVERT TO TIMEOUT INSTEAD OF NEWER DELAY
            // THE ALLEDGED BUGGY CODE IS BELOW:
            //this.currentTimeout = this._onTimeout.bind(this).delay(timeout);
        this.xmlRequest.open('GET', url, true);
        this.xmlRequest.onreadystatechange = this.onStateChange.bind(this);
        this.xmlRequest.send(null);
        return true;
    },
    getRawData: function(url, timeout) {
        this.useJson = false;
        this.get(url, timeout);
    },
    post: function(url, data, timeout) {
        if (!this.reset())
            return false;
        if (timeout !== undefined)
            this.currentTimeout = setTimeout(this._onTimeout.bind(this), timeout);
        this.xmlRequest.open('POST', url, true);
        this.xmlRequest.setRequestHeader("Content-Type", "ygame/data");
        this.xmlRequest.setRequestHeader("Connection", "close");
        this.xmlRequest.onreadystatechange = this.onStateChange.bind(this);
        this.xmlRequest.send(JSON.stringify(data) || 'null');
        return true;
    },
    //************************************************************************
    // PRIVATE
    //************************************************************************
    _onLoad: function() {
        var result;
        this.abort(); // Clears the timeout
        var status = this.xmlRequest.status;
        if (status >= 200 && status < 300)
        {
            if (this.useJson)
            {
                try {
                    result = eval('('+this.xmlRequest.responseText+')');
                }
                catch (e)
                {
                    alert('error in web service call: ' + this.inspect());
                    result = null;
                }
                this._updateInnerHtml(result);
            }
            else
            {
                result = this.xmlRequest.responseText;
            }
        }
        else
        {
            alert('error in web service call: status return is ' + status);
            result = null;
        }
        this.onLoad(status, result);
    },
    _updateInnerHtml: function(result) {
        if (typeof(result) == 'object' && result !== null)
        {
            $H(result.html).each(function(pair) {
                if (div = $(pair.key)) {
                    div.update(pair.value.value)
                    if (typeof pair.value.css != 'undefined') {
                        div.addOnlyClassName(pair.value.css);
                    }
                }
            });
        }
    },
    _onTimeout: function() {
        this.abort(); // Clears the timeout
        this.onTimeout();
    },
    //************************************************************************
    // PROTECTED (each may be overriden)
    //************************************************************************
    onLoading: Prototype.emptyFunction,
    onLoad: Prototype.emptyFunction,
    onTimeout: Prototype.emptyFunction
});

function sendPostRequest(url, args){
    postRequest = new yRemote();
    postRequest.post(url, args);
}

/*
    minified json2.js
    2008-02-14
*/

if(!this.JSON){JSON=function(){function f(n){return n<10?'0'+n:n;}
Date.prototype.toJSON=function(){return this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z';};var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};function stringify(value,whitelist){var a,i,k,l,r=/["\\\x00-\x1f\x7f-\x9f]/g,v;switch(typeof value){case'string':return r.test(value)?'"'+value.replace(r,function(a){var c=m[a];if(c){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+
(c%16).toString(16);})+'"':'"'+value+'"';case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
if(typeof value.toJSON==='function'){return stringify(value.toJSON());}
a=[];if(typeof value.length==='number'&&!(value.propertyIsEnumerable('length'))){l=value.length;for(i=0;i<l;i+=1){a.push(stringify(value[i],whitelist)||'null');}
return'['+a.join(',')+']';}
if(whitelist){l=whitelist.length;for(i=0;i<l;i+=1){k=whitelist[i];if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}else{for(k in value){if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}
return'{'+a.join(',')+'}';}}
return{stringify:stringify,parse:function(text,filter){var j;function walk(k,v){var i,n;if(v&&typeof v==='object'){for(i in v){if(Object.prototype.hasOwnProperty.apply(v,[i])){n=walk(i,v[i]);if(n!==undefined){v[i]=n;}else{delete v[i];}}}}
return filter(k,v);}
if(/^[\],:{}\s]*$/.test(text.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof filter==='function'?walk('',j):j;}
throw new SyntaxError('parseJSON');}};}();}
