﻿function httpReq(url, callback)
{
	this._url = url;
	this._action = callback;
	this._httpInterface = null;

	// Initialise XMLHttpRequest object
	this.resetInterface();

	return true;
}

/* Check if the httpReq object is available */
httpReq.prototype.isAvailable = function()
{
	if (this.httpInterface == null)
	{
		return false;
	}
	
	return true;
}

/* Execute the action which has been associated with the completion of this object */
httpReq.prototype.executeAction = function()
{
	// If XMLHR object has finished retrieving the data
	if (this.httpInterface.readyState == 4)
	{
		// If the data was retrieved successfully
		try
		{
			if (this.httpInterface.status == 200)
			{
				this._action();
			}
			// IE returns status = 0 on some occasions, so ignore
			else if (this.httpInterface.status != 0)
			{
				writeLine("There was an error while retrieving the URL: " + this.httpInterface.statusText);
			}
		}
		catch (error)
		{
		    writeLine(error.name + ": " + error.description);
		}
	}

	return true;
}

/* Return responseText */
httpReq.prototype.getResponseText = function()
{
	return this.httpInterface.responseText;
}

httpReq.prototype.getJsonObj = function ()
{
    var response = this.getResponseText();
    //writeLine("getJsonObj response: " + response);
    var obj = null;
    
    if (null != response && response.length > 0)
    {
        try 
        {
            obj = parseJson(response, dateFilter);
        }
        catch (error)
        {
            writeLine(error.name + ": " + error.description);
            obj = null;
        }
    }
    
    return obj;
}
/* Initialise object and load URL */
httpReq.prototype.loadUrl = function(url)
{
	this.resetInterface();
	writeLine("loadUrl: " + url);
	this.httpInterface.open("GET", url);
	this.httpInterface.send(null);
    return true;
}


httpReq.prototype.load = function()
{
	this.resetInterface();
	this.httpInterface.open("GET", this._url);
	this.httpInterface.send(null);
    return true;
}

/* Turn off existing connections and create a new XMLHR object */
httpReq.prototype.resetInterface = function()
{
	var self = this;

	if (this.httpInterface != null && this.httpInterface.readyState != 0 && this.httpInterface.readyState != 4)
	{
		this.httpInterface.abort();
		
	}
    if (this.httpInterface == null)
        this.httpInterface = getHttpObj();
    
	this.httpInterface.onreadystatechange = function()
		{
			self.executeAction();

			return true;
		};

	return true;
}

/* Assign the function which will be executed once the XMLHR object finishes retrieving data */
httpReq.prototype.setAction = function(actionFunction)
{
	this.action = actionFunction;

	return true;
}

function getHttpObj()
{
    var httpObj = null;
    try
    {
        httpObj = new ActiveXObject("Msxml2.XMLHTTP");
    }   
    catch (err0)
    {
        try
        {
            httpObj = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch (err1)
        {
            try
		    {
		        httpObj = new XMLHttpRequest();	
		    }
		    catch (err2)
		    {
		        httpObj = null;
		    }
        }
    }
	return httpObj;
}

function htmlEncode(s) {
        var str = new String(s);
        str = str.replace(/&/g, "&#38;");
        str = str.replace(/</g, "&#60;");
        str = str.replace(/>/g, "&#62;");
        str = str.replace(/"/g, "&#34;");
        str = str.replace(/'/g, "&#39;");
        
        return str;
} 

function dateFilter(key, value)
{
    if (key === "dateTime")
    {
        var newvalue = value.replace("/Date(", "").replace(")/", "");
        var dt = new Date(parseInt(newvalue));
        return dt;
    }
    else
        return value; 
}

function walkObj(k, v, filter) 
    {
        var i;
        if (v && typeof v === 'object') 
        {
            for (i in v) 
            {
                if (Object.prototype.hasOwnProperty.apply(v, [i])) 
                {
                    v[i] = walkObj(i, v[i], filter);
                }
            }
        }
        return filter(k, v);
}

function parseJson (text, filter) 
 {
    var j;

    function walk(k, v) 
    {
        var i;
        if (v && typeof v === 'object') 
        {
            for (i in v) 
            {
                if (Object.prototype.hasOwnProperty.apply(v, [i])) 
                {
                    v[i] = walk(i, v[i]);
                }
            }
        }
        return filter(k, v);
    }
    
    if (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/.test(text.
            replace(/\\./g, '@').
            replace(/"[^"\\\n\r]*"/g, ''))) 
    {
        j = eval('(' + text + ')');
        return typeof filter === 'function' ? walk('', j) : j;
    }
    
    throw new SyntaxError('parseJSON');
}

function StringBuilder(value)
{
    this.strings = new Array("");
    this.append(value);
}

StringBuilder.prototype.append = function (value)
{
    if (value)
    {
        this.strings.push(value);
    }
}

StringBuilder.prototype.clear = function ()
{
    this.strings.length = 1;
}

StringBuilder.prototype.toString = function ()
{
    return this.strings.join("");
}

function writeLine(text)
{  
    var console = document.getElementById("console");
    if (console)
    {
        var sb = new StringBuilder((console.value) ? console.value : "");
        sb.append(text);
        sb.append("\n\n");
        console.value = sb.toString();
        console.scrollTop = console.scrollHeight;
    }
}

function setInnerHtml(domElemName, value)
{
    domElem = document.getElementById(domElemName);
    if (domElem)
        domElem.innerHTML = value;
}

function setClass(domElemName, value)
{
    domElem = document.getElementById(domElemName);
    if (domElem)
        domElem.setAttribute("class", value);
}

// Format integers to have at least two digits.
function formatInt(n) 
{    
    return n < 10 ? '0' + n : n;
}

Date.prototype.toJSON = function () 
{
    return this.getUTCFullYear()   + '-' +
         formatInt(this.getUTCMonth() + 1) + '-' +
         formatInt(this.getUTCDate())      + 'T' +
         formatInt(this.getUTCHours())     + ':' +
         formatInt(this.getUTCMinutes())   + ':' +
         formatInt(this.getUTCSeconds())   + 'Z';
};

Date.prototype.getTimeString = function () 
{
    var ap = "";
    var hours = this.getHours();
    if (hours > 12)
    {
        ap = "PM"
        hours  = hours - 12 ;
    }
    else if (hours == 12)
        ap = "PM";
    else if (hours < 12)
    {
        ap = "AM";
    }   
    
    return hours + ":" + formatInt(this.getMinutes()) + " " + ap;
};

// table of character substitutions
var m = 
{    
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '"' : '\\"',
    '\\': '\\\\'
};

function stringify(value, whitelist) 
{
    var a,          // The array holding the partial texts.
        i,          // The loop counter.
        k,          // The member key.
        l,          // Length.
        r = /["\\\x00-\x1f\x7f-\x9f]/g,
        v;          // The member value.

    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(',') + '}';
    }
}