﻿    
var cachedArgs = null;
  
function encode_utf8(str) {

 var Data = str;
 var utf8txt = "";

 // Data = Data.replace(/\r\n/g,"\n");

 for(var n=0; n<Data.length; n++)
 {
 var c=Data.charCodeAt(n);
 // all chars from 0-127 => 1byte
 if (c<128)
 utf8txt += String.fromCharCode(c);
 // all chars from 127 to 2047 => 2byte
 else if((c>127) && (c<2048)) {
 utf8txt += String.fromCharCode((c>>6)|192);
 utf8txt += String.fromCharCode((c&63)|128);
 }
 // all chars from 2048 to 66536 => 3byte
 else {
 utf8txt += String.fromCharCode((c>>12)|224);
 utf8txt += String.fromCharCode(((c>>6)&63)|128);
 utf8txt += String.fromCharCode((c&63)|128);}
 }

 return escape(utf8txt);

 }
 


	

function typeOf(value) {
    if (value == undefined) {
        return "undefined";
    }
    if (value instanceof Object) {
        if (value instanceof Boolean) {
            return "Boolean";
        } else if (value instanceof Number) {   
            if (/\./.test(value)) {
                return "Float";
            } else {
                return "Int";
            }
        } else if (value instanceof String) {
            return "String";
        } else if (value instanceof Array) {
            return "Array";
        } else if (value instanceof Date) {
            return "Date";
        } else if(value instanceof Function) {
            return "Function";
        } else if (value instanceof Object ) {
            return "Object";
        } 
    
    } else if (typeof value) {
        if (typeof value == "object") {
            if (typeof value == "object" && !value) {
                return "null";
            } 
        } else {
            if (typeof value == "boolean") {
                return "boolean";
            } else if (typeof value == "number") {
                if (/\./.test(value)) {
                    return "float";
                } else {
                    return "int";
                }
            } else if (typeof value == "string") {
                return "string";
            }
        }
    } else {
        return false;
    }
}

      
cfw_prepareParameters = function(params) {
     
     var sb = new Sys.StringBuilder();
     
     for(p in params)
     {  
        if(typeOf(params[p]) == "Date")
        {
            sb.append(params[p].format("s"));
        }
        else if(params[p] == null)
        {
            sb.append("null");
        }
        else if(typeof(params[p]) == "object" && params[p].__type && params[p].__sig)
        {
            sb.append( params[p].getSig() );
        }
        else if(typeOf(params[p]) == "String" || typeOf(params[p]) == "string")
        {
            sb.append(encode_utf8(params[p]));
        }
        else
        {
            sb.append(params[p]);
        }
        
        sb.append("~");
      }
        var rv = sb.toString();
        return rv.substr(0, rv.length-1);   
    }
    
    cfw_sendReq = function(url, onSuccess, onFailure, asm, args, method)
    {
        var wRequest = new Sys.Net.WebRequest();
       
        wRequest.set_httpVerb(method);
        wRequest.add_completed(function(e,x){cfw_prepareResponse(e,onSuccess,onFailure);});
        wRequest.set_timeout(1500);
        
        var hash = hex_md4(url);
        
        var splittedUrl = url.split('$');
        var params = splittedUrl[1];
        
        if(method == "POST")
        {
            splittedUrl[1] = hash;
            url = splittedUrl.join('$');
            
            var body = "p=" + params;
            wRequest.set_body(body);
            wRequest.get_headers()["Content-Length"] = body.length;
        }
        
        if(asm && asm.length > 0)
            wRequest.get_headers()["X-Corvus-Asm"] = asm;
            
        wRequest.get_headers()["X-Corvus-Args"] = hash;
        wRequest.get_headers()["X-Corvus-URI"] = params;
        
        wRequest.set_url(url);
        wRequest.invoke(); 
        
         if(typeOf(args) != "undefined") 
            cfw_setArgsCache(hash,args);
            
       return wRequest;
    }
    
     
    cfw_get = function(url, onSuccess, onFailure, asm, args) {
    
        return cfw_sendReq(url, onSuccess, onFailure, asm, args, "GET");
    }
    
    
     cfw_post = function(url, onSuccess, onFailure, asm, args) {
     
        return cfw_sendReq(url, onSuccess, onFailure, asm, args, "POST");
    }
    
    cfw_setArgsCache = function(hash, args)
    {
      if(cachedArgs == null)
            cachedArgs = new Hashtable();
            
       cachedArgs.put(hash, args);
    }
    
    cfw_getArgsCache = function(executor)
    {
        var argsHeader = executor.getResponseHeader("X-Corvus-Args");
        
        if(!argsHeader || !cachedArgs)
            return null;
            
         var value = cachedArgs.get(argsHeader);
         
         /*
         if(value != null)
         {
          cachedArgs.remove(argsHeader);
         }
         
         
        
         cachedArgs.moveLast();
         
         while (cachedArgs.previous())
         {
           if((+ new Date) - cachedArgs.getKey() >  15000)
                cachedArgs.remove(cachedArgs.getKey());
         }
         */
         
         return value;
            
    }
    
    
    retryReq = function(timeoutedReq, onSuccess, onFailure)
    {
        var wRequest = new Sys.Net.WebRequest();
       
        wRequest.set_httpVerb(timeoutedReq.get_httpVerb());
        wRequest.add_completed(function(e,x){cfw_prepareResponse(e,onSuccess,onFailure);});
        wRequest.set_timeout(3000);
        
        if(timeoutedReq.get_httpVerb() == "POST")
        {
            wRequest.set_body(timeoutedReq.get_body());
            wRequest.get_headers()["Content-Length"] = timeoutedReq.get_body().length;
        }
        
        if(timeoutedReq.get_headers()["X-Corvus-Asm"]!=null)
            wRequest.get_headers()["X-Corvus-Asm"] = timeoutedReq.get_headers()["X-Corvus-Asm"];
            
        wRequest.get_headers()["X-Corvus-Args"] = timeoutedReq.get_headers()["X-Corvus-Args"];
        wRequest.get_headers()["X-Corvus-URI"] = timeoutedReq.get_headers()["X-Corvus-URI"];
        
        wRequest.set_url( timeoutedReq.get_url());
        wRequest.invoke(); 
        
    }
    
    cfw_prepareResponse = function(executor, onSuccess, onFailure)
    {
        var response = null;
    
        if(executor.get_aborted())
        {
            onFailure({"IsSucceded":false,"ResponseType":"Aborted","Message":"Request aborted"});
            return;
        }
        else if (executor.get_timedOut())
        {
            var req = executor.get_webRequest();
            if(req.get_timeout() == 1500)
            {
                retryReq(req, onSuccess, onFailure);
                return;
            }
            else
            {
                onFailure({"IsSucceded":false,"ResponseType":"TimeOut","Message":"Request timed out"});
                return;
            }
        }
        else
        {
            var statusCode;
            try 
            {
                statusCode = executor.get_statusCode();
            }
            catch(e)
            {
                statusCode = 0;
            }
            
            if(statusCode != 567 && statusCode != 403)
            {   
                if((statusCode < 100) || (statusCode >= 600))
                {
                    onFailure({"IsSucceded":false,"ResponseType":"ConnectionError","Message":"Connection error."});
                    return;
                }
                else if((statusCode < 200) || (statusCode >= 300))
                {
                    onFailure({"IsSucceded":false,"ResponseType":"HTTPError","Message":"HTTP error."});
                    return;
                }
            }
        }
        
        try
        {
            response = cfw_deSerialize(executor.get_responseData());
        }
        catch(err)
        {
              onFailure({"IsSucceded":false,"ResponseType":"SerializationError","Message":"Serialization error."});
                    return;
        }
        
        
        response=cfw_cast(response);
        
        if(!response[0].IsSucceeded)
            onFailure(response[0], cfw_getArgsCache(executor));
        else
            onSuccess(response[1], cfw_getArgsCache(executor));
        
    }

    cfw_parseSig = function(obj)
    {
        var sb = new Sys.StringBuilder();
        var arr = obj.__sig.split(',');
        for(var s in arr)
        {   
            sb.append("'");
            sb.append(obj[arr[s]]);
            sb.append("'");
            
            if(s<arr.length-1)
                sb.append(",");
        }
        return sb.toString();
    }
    
    cfw_deSerialize = function(json)
    {
        return eval("(" + json + ")");
    }
     
     cfw_cast = function(obj)
     {
        
        if(obj == null)
            return null;
        
        if(!obj.__type && (typeOf(obj)=="Array" || typeOf(obj)=="Object"))
        {
           for(element in obj)
              obj[element] = cfw_cast(obj[element]);
              
           return obj;
        }
        
        if(!obj.__type)
            return obj;
        
        var type = obj.__type;
        var instance = eval("new " + type + "(" + cfw_parseSig(obj) + ");");
        
        for(var property in instance)
        {
            if(typeof(instance[property])!="function")
                instance[property] = cfw_cast(obj[property]);
        }
        return instance;
     }

Type.registerNamespace("Corvus.JsBase");

Corvus.JsBase.Base = function (type, sig)
{

}

Corvus.JsBase.Base.prototype = {
    
    getSig: function() {
    sigArr = this.__sig.split(',');
    var sig = "";
    
    for (var i = 0; i < sigArr.length; i++)
      sig +=  (this[sigArr[i]].__type ?  this[sigArr[i]].getSig() : sigArr[i] + "=" + this[sigArr[i]]) + ",";

     return sig.substr(0, sig.length-1);
    }
}

Corvus.JsBase.Base.registerClass("Corvus.JsBase.Base");



if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
