// SLICKBACK
//

SlickBackHandler.prototype.bind = function(object, method) 
{
    return function() 
    {
        return method.apply(object);
    }
}

SlickBackHandler.prototype.setProgressDisplay = function(theForm, visibility)
{
    var progressDivIDs = theForm.__SLICKBACKPROGRESS.value
    if (progressDivIDs != null && progressDivIDs.length > 0)
    {
        var divIDs = progressDivIDs.split(',');
        
        var i;
        for (i=0; i<divIDs.length; i++)
        {
            var div = document.getElementById(divIDs[i]);
            if (!div)
                continue;
                
            div.style.visibility = visibility;
        }
    }
}

SlickBackHandler.prototype.fire = function(eventTarget, eventArgument, notify)
{
    // Store notification handler
    this.notify = notify;

    // Set slickback values
    var theForm = document.forms['aspnetForm'];
    if (!theForm)
        return;

    theForm.__SLICKBACKTARGET.value = eventTarget.split("$").join(":");
    theForm.__SLICKBACKARGUMENT.value = eventArgument;

    // Make request
    if (this.supportsXMLHttpRequest())
    {  
        // Reflect loading status
        this.setProgressDisplay(theForm, '');

        // Use XMLHttpRequest
        theForm.__SLICKBACKTYPE.value = '2';

        var body = this.processFormElements(theForm);
        this.postXMLDoc(theForm.action, body);

        // Reset values since the page isn't refreshed
        theForm.__SLICKBACKTARGET.value = '';
        theForm.__SLICKBACKARGUMENT.value = '';
        theForm.__SLICKBACKTYPE.value = '';
    }
    else
    {
        // Use vanilla post
        theForm.__SLICKBACKTYPE.value = '0';
        
        theForm.submit();
    }
}

SlickBackHandler.prototype.getUrl = function(url, notify) 
{
    if (!this.supportsXMLHttpRequest())
        return;

    // Store notification handler
    this.notify = notify;

    // Reflect loading status
    var theForm = document.forms['aspnetForm'];
    if (theForm)
    {
        this.setProgressDisplay(theForm, '');
    }

    // Make request
    this.postXMLDoc(url, '__SLICKBACKTYPE=1');
}

SlickBackHandler.prototype.processFormElements = function(theForm) 
{
    var r = '';
    var count = theForm.elements.length;

    var i;
    for (i=0; i<count; i++) 
    {
        var element = theForm.elements[i];
        var elementName = element.tagName.toLowerCase();

        if (elementName == "input") 
        {
            if (element.type == "submit" || element.type == "image")
                continue;

            if (element.type == "checkbox" || element.type == "radio")
            {
                if (!element.checked)
                    continue;
            }

            r += element.name + "=" + encodeURIComponent(element.value) + "&";
        }
        else if (elementName == "textarea")
        {
            r += element.name + "=" + encodeURIComponent(element.value) + "&";
        }
        else if (elementName == "select") 
        {
            var selectCount = element.options.length;

            var j;
            for (j=0; j<selectCount; j++) 
            {
                var option = element.options[j];

                if (option.selected == true)
                    r += element.name + "=" + encodeURIComponent(option.value) + "&";
            }
        }
    }

    return r;
}

SlickBackHandler.prototype.supportsXMLHttpRequest = function() 
{
    if (window.XMLHttpRequest)
        return true;

    if (window.ActiveXObject) 
    {
        if (new ActiveXObject("Microsoft.XMLHTTP"))
            return true;
    }

    return false;
}

SlickBackHandler.prototype.postXMLDoc = function(url, body) 
{
    // Native object
    if (window.XMLHttpRequest) 
    {
        this.client = new XMLHttpRequest();
        this.client.onreadystatechange = this.bind(this, this.xmlRequestChange);
        this.client.open("POST", url, true);
        this.client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");            
        this.client.send(body);
    } 
    // ActiveX object
    else if (window.ActiveXObject) 
    {
        this.client = new ActiveXObject("Microsoft.XMLHTTP");
        if (this.client) 
        {
            this.client.onreadystatechange = this.bind(this, this.xmlRequestChange);
            this.client.open("POST", url, true);
            this.client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            this.client.send(body);
        }
    }
}

SlickBackHandler.prototype.xmlRequestChange = function() 
{
    // Loaded
    if (this.client.readyState == 4) 
    {
        if (this.client.status == 200) 
        {
            this.xmlRequestDone();
        } 
        else 
        {
            document.body.innerHTML = this.client.responseText;
        }
    }
}

SlickBackHandler.prototype.xmlRequestDone = function()
{
    //alert(this.client.responseText);
    //return;

    var i;
    var root = this.client.responseXML.documentElement;  

    var redirect = SlickBack.childValue(root, 'redirect');
    if (redirect)
    {
        window.location = redirect;
        return;
    }

    var theForm = document.forms['aspnetForm'];
    if (theForm)
    {
        var inputValues = root.getElementsByTagName('inputValue');
        for (i=0; i<inputValues.length; i++)
        {
            var inputValue = inputValues.item(i);
            var inputID = inputValue.getAttribute('id');
            var input = theForm.elements[inputID];
            if (input)
                input.value = SlickBack.nodeValue(inputValue);
        }
    }
    
    var payloads = root.getElementsByTagName('payload');
    for (i=0; i<payloads.length; i++)
    {
        var payload = payloads.item(i);
        var handler = payload.getAttribute('handler');
        eval(handler + '(payload)');
    }

    // Reflect loading status
    if (theForm)
    {
        this.setProgressDisplay(theForm, 'hidden');
    }
    
    // Send notification
    if (this.notify)
        this.notify();
}

function SlickBackHandler()
{
    this.client = null;
    this.notify = null;
}

var SlickBack = {
    fire: function(eventTarget, eventArgument, notify)
    {
        var handler = new SlickBackHandler();
        handler.fire(eventTarget, eventArgument, notify);
    },
    getUrl: function(url, notify)
    {
        var handler = new SlickBackHandler();
        handler.getUrl(url, notify);
    },
    handleContent: function(node)
    {
        var contents = node.getElementsByTagName('content');

        var i;
        for (i=0; i<contents.length; i++)
        {
            var content = contents.item(i);
            var divID = content.getAttribute('id');
            var div = document.getElementById(divID);
            if (div)
                div.innerHTML = SlickBack.nodeValue(content);
        }
    },
    handleOnLoad: function(node)
    {
        eval(SlickBack.nodeValue(node));
    },
    childValue: function(node, tagName)
    {
        var elements = node.getElementsByTagName(tagName);
        if (elements.length == 0)
            return null; 

        var item = elements.item(0).firstChild;
        return (item == null) ? '' : item.nodeValue;
    },
    nodeValue: function(node)
    {
        return (node.firstChild == null) ? '' : node.firstChild.nodeValue
    }
}