/**
 * duUpdateRDSEmulator function
 *   Sends Ajax-request to server and if success, updates span with RDSEmulator,
 *		than sets timer up to song end
 *   If request is failed, sets timeout for 30 secs
 * author:	Ivan Dobrovolski <i.riban@gmail.com>
 */

function doUpdateRDSEmulator ()
{
	if (!window.g_oSerializer)
	{
		window.g_oSerializer = new Serializer();
	}
	
	var oSpan = document.getElementById ('RDSEmulator');
	oSpan.style.visibility = 'hidden';

	(new AjaxRequest).send({
			url       : (/www/.test(window.location.href) ? "http://www.roks.ru/_ajax/response.php" : "http://roks.ru/_ajax/response.php"),
			data      : {},
			onSuccess : function(data, info)
			{       
					if (data)
					{
						var nTime  = ( (parseInt (data['time']) + parseInt(data['length']) ) * 1000) - new Date() . getTime();

						oSpan.innerHTML = '<b>Сейчас в эфире:</b> ' + data['name'];
						if (nTime > 0 && parseInt(data['length']) > 60)
						{
							oSpan.style.visibility = 'inherit';
						}

						if (data['name'].match(/^Radio ROKS/i) )
						{
							nTime = 60000;
						}
						else
						{
							nTime = nTime > 0 ? (nTime + 5000) : 10000;
						}
						setTimeout ("doUpdateRDSEmulator()", nTime);
					}
			},
			onTimeout : function(info)
			{
					//alert("Connection to '"+info.url+"' has timed out");
					setTimeout ("doUpdateRDSEmulator()", 30000);
			},
			onError   : function(info)
			{
					//alert("Ooops!\n\nOoops' status: "+info.conn.status+" ("+info.conn.statusText+")");
			}
	});

}

/**
 * AjaxRequest class
 * author:	Ivan Dobrovolski <i.riban@gmail.com>
 */

function AjaxRequest() {}
(
function()
{
    var timeoutDefault = 10 * 1000;        // 10 seconds

    AjaxRequest.prototype =
    {
            info             : null,
            cached           : false,
            isReady          : true,
            isTimedOut       : false,
            timeoutInterval  : null,

            send : function(info)
            {
                try
                {
                    if (!this.isReady)
                    {
                        throw new Error("The component is occupied.\nYou have to create another one.");
                    }
                    this.isReady = false;

                    if ("object" != typeof (info) )
                    {
                        throw new Error ("Wrong parameter to send() method");
                    }

                    if ( !(info.conn = this.getConnection() ) )
                    {
                        throw new Error ("Can't create connection.");
                    }

                    var self = this;
                    info.conn.onreadystatechange = function()
                    {
                        self.onReadyStateChange();
                    }
                    info.parent = this;

                    if ("boolean" != typeof (info.async) )
                    {
                        info.async = true;
                    }

                    if ("string" != typeof (info.url) || !info.url.length)
                    {
                        throw new Error ("Please, set the URL.");
                    }

                    if ("string" != typeof (info.method) )
                    {
                        info.method = "post";
                    }
                    info.method = info.method.toLowerCase();

                    var queryString = ("object" == typeof (info.data) ) ? this.serialize (info.data) : escape (info.data);

                    if ("post" != info.method)
                    {
                        if (!this.cached)
                        {
                            info.url += (info.url.indexOf ("?") < 0 ? "?" : "&") + "ajaxRequestUncache=" + parseInt (Math.random() * 1000000);
                        }

                        if (queryString.length > 0)
                        {
                            info.url += (info.url.indexOf("?") < 0 ? "?" : "&") + queryString;
                        }
                    }

                    if("string" != typeof(info.username)) info.username = null;
                    if("string" != typeof(info.password)) info.password = null;

                    info.timeout = "number" == typeof (info.timeout) ? Math.max (0, info.timeout) : timeoutDefault;
                    this.isTimedOut = false;
                    if(info.timeout > 0)
                    {
                        this.timeoutInterval = setTimeout( function()
                                                           {
                                                               self.onTimeout();
                                                           }, info.timeout);
                    }

                    info.result = {};
                    this.info = info;

                    info.conn.open(info.method, info.url, info.async, info.username, info.password);
                    try
                    {
                        info.conn.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                        if("post" == info.method)
                        {
                            info.conn.setRequestHeader("Content-length", queryString.length);
                        }
                    }
                    catch (e) {}

                    info.conn.send("post" == info.method ? queryString : null);

                    if(!info.async)
                    {
                        this.info.result = this.getResult();
                        return this.info.result;
                    }

                }
                catch (e)
                {
                    //alert ("AjaxRequest error\n\n" + e.message);
                }

            },

            onReadyStateChange : function()
            {
                switch (this.info.conn.readyState)
                {
                case 0 :
                    break;

                case 1 :
                    if (this.info.onConnecting)
                    {
                        this.info.onConnecting (this.info);
                    }
                    break;

                case 2 :
                    if (this.info.onConnected)
                    {
                        this.info.onConnected (this.info);
                    }
                    break;

                case 3 :
                    if (this.info.onData)
                    {
                        this.info.onData (this.info);
                    }
                    break;

                case 4 :
                    this.isReady = true;
                    if (this.isTimedOut)
                    {
                        break;
                    }
                    if (this.timeoutInterval)
                    {
                        clearInterval (this.timeoutInterval);
                        this.timeoutInterval = null;
                    }

                    switch (this.info.conn.status)
                    {
                    case 200 : // everything's OK

                        this.info.result = this.getResult();

                        if (this.info.result._ERROR)
                        {
                            //alert ("AjaxRequest server side error\n\n"+this.info.result._ERROR);
                        }

                        if (this.info.onSuccess)
                        {
                            this.info.onSuccess (this.info.result, this.info);
                        }
                        break;

                    case 12029 : // timed out by system
                        this.onTimeout();
                        break;

                    default :
                        if (this.info.onError)
                        {
                            this.info.onError (this.info);
                        }
                    }
                }
            },

            onTimeout : function()
            {
                if (this.timeoutInterval)
                {
                    clearInterval (this.timeoutInterval);
                    this.timeoutInterval = null;
                }

                this.isTimedOut = true;
                this.isReady = true;

                try
                {
                    this.info.conn.abort();
                }
                catch(e) {}

                if (this.info.onTimeout)
                {
                    this.info.onTimeout (this.info);
                }
            },

            getConnection : function()
            {
                var conn = null;

                try
                {
                    conn = new XMLHttpRequest;
                } catch(e) {}

                if (!conn) try
                {
                    conn = new ActiveXObject("Msxml2.XMLHTTP");
                }
                catch(e) {}

                if (!conn) try
                {
                    conn = new ActiveXObject("Microsoft.XMLHTTP");
                }
                catch(e) {}

                if (!conn)
                {
                    //alert ("AjaxRequest error\n\nYour browser doesn't support Ajax!");
                }

                return conn;
            },

            getResult : function ()
            {
				//return this.info.conn.responseText.length ? this.unserializeWddx (this.info.conn.responseXML.getElementsByTagName("struct")[0]) : {};
				return this.unserialize (this.info.conn.responseText);
            },

            serialize : function (data)
            {
                if ("object" != typeof (data) || null === data || data instanceof Array)
                {
                    //alert ("AjaxRequest error\n\nOnly objects can be serialized");
                    return "";
                }

                return this.serializeObject("", data).join("&");
            },

            serializeObject : function (prefix, data)
            {
                if (null === data)
                {
                    return prefix.length ? [prefix + "="] : [];
                }

                var vars = new Array;

                switch(typeof(data))
                {
                case "object" :
                    if (data instanceof Array)
                    {
                        for (var i=0; i < data.length; i++)
                        {
                            vars = vars.concat (this.serializeObject (prefix + "[" + i + "]", data[i]) );
                        }
                    }
                    else
                    {
                        for(var i in data)
                        {
                            vars = vars.concat (
                                this.serializeObject (prefix.length ? prefix + "["+escape(i) + "]" : escape(i), data[i])
                                );
                        }
                    }
                    break;

                case "string" :
                case "number" :
                    vars.push (prefix + "=" + escape(data) );
                    break;

                case "boolean" :
                    vars.push (prefix + "=" + (data ? 1 : 0));
                break;
                }

                return vars;
            },

            unserialize : function (str)
			{
				return window.g_oSerializer.unserialize (str);
			},
			
			
			unserializeWddx : function (dom)
            {
                if("undefined" == typeof (dom) || "null" == typeof (dom) )
                {
                    return {};
                }

                switch(dom.nodeName)
                {
                case "struct" :
                    var result = {};
                    for (var i=dom.firstChild; i; i = i.nextSibling)
                    {
                        if("var" != i.nodeName) continue;
                        result[i.getAttribute("name")] = this.unserializeWddx(i.firstChild);
                    }
                    return result;

                case "array" :
                    var result = new Array;
                    for (var i=dom.firstChild; i; i = i.nextSibling)
                    {
                        result.push(this.unserializeWddx(i));
                    }
                    return result;

                    case "string" :
                    if (!dom.firstChild)
                    {
                        return "";
                    }

                    if (dom.firstChild.nextSibling)
                    {
                        var result = "";
                        for (var i=dom.firstChild; i; i = i.nextSibling)
                        {
                            if (1 == i.nodeType && "char" == i.nodeName)
                            {
                                result += String.fromCharCode (parseInt (i.getAttribute("code"), 16) );
                            }
                            else if (3 == i.nodeType)
                            {
                                result += i.nodeValue;
                            }
                        }
                        return result;
                    }
                    return dom.firstChild.nodeValue;

                case "number" :
                    return Number (dom.firstChild.nodeValue);

                case "boolean" :
                    return "true" == dom.getAttribute("value") ? true : false;

                case "null" :
                    return null;
                }
            }
    }
}
) ();