var ajaxFormRequests = new Array();
var ajaxRequests = 0;
var ajaxSuggestRequests = new Array();
var ajaxSuggestValues = new Array();

function ajaxClose()
{
    $('ajaxBackground').hide();
    $('ajaxContainer').hide();
    Element.update($('ajaxContent'), '');
}

function ajaxLoader(update)
{
    ajaxRequests += update;
    if(ajaxRequests > 0)
        $('ajaxLoader').show();
    else
        $('ajaxLoader').hide();
}

function ajaxForm(e)
{
    var id = Element.identify(e);
    
    // prevent double requests
    if(ajaxFormRequests[id] != true)
    {
        ajaxFormRequests[id] = true;

        // update ajaxLoader
        ajaxLoader(1);
    
        // close all ajaxSuggestArea's
        $$('.ajaxSuggestArea').each(function(item) { Element.update(item, ''); });
    
        // start request
        e.request({
            onSuccess: function(transport)
            {
                ajaxTransport(transport);
                ajaxFormRequests[id] = false;
                ajaxLoader(-1);
            },
            onFailure: function()
            {
                alert('Failed to receive AJAX response!');
                ajaxFormRequests[id] = false;
                ajaxLoader(-1);
            }
        });
    }
}

function ajaxInit()
{
    // observe objects
    $$('form.ajaxForm').invoke('observe', 'submit', function(event) { ajaxForm(this); event.stop(); });
    $$('a.ajaxLink').invoke('observe', 'click', function(event) { ajaxLink(this); event.stop(); });
    $$('input.ajaxSuggest').invoke('observe', 'keyup', function(event) { ajaxSuggest(this); });
    $$('a.ajaxSuggest').invoke('observe', 'click', function(event) { ajaxSuggestA(this); event.stop(); });
}

function ajaxJs(file)
{
    var j = new Element('script', { 
        type: "text/javascript", 
        language: "javascript", 
        src: file 
    });

    $(document.body).insert(j);
}

function ajaxLink(e, target)
{
    ajaxUrl(e.href, target);
}

function ajaxSuggestDelay(e, old_value)
{
    var id = Element.identify(e);
    var value = e.getValue();
    
    if(old_value == value && value.length > 1)
    {
        if(ajaxSuggestValues[id] != value)
        {
            ajaxSuggestValues[id] = value;
            var target = id + '_ajaxSuggestArea';
            var url = e.form.action;
            if(url.include('?'))
                url += '&';
            else
                url += '?';
            url += 'ajaxSuggestElementId=' + id + '&ajaxSuggestValue=' + value;
            new Ajax.Request(url,
            {
                method:'get',
                onSuccess: function(transport)
                {
                    ajaxTransport(transport, target);
                },
                onFailure: function()
                {
                    alert('Failed to receive AJAX response!');
                }
            });
        }
    }
}

function ajaxSuggest(e)
{
    var value = e.getValue();
    
    setTimeout(function() { ajaxSuggestDelay(e, value); }, 250);
}

function ajaxSuggestA(e)
{
    var tmp = e.href.split('#');
    
    // clear value
    ajaxSuggestValues[tmp[1]] = null;

    // hide suggestions
    $(tmp[1] + '_ajaxSuggestArea').hide();
    
    // insert value
    $(tmp[1]).value = e.innerHTML;
}

function ajaxTransport(transport, target)
{
    if(!target)
        target = 'ajaxContent';
    var response = transport.responseText || 'empty';
    if(response == 'empty')
        alert('Received empty AJAX response!');
    else
    {
        // update element
        if(transport.getHeader('ajaxTarget'))
            target = transport.getHeader('ajaxTarget');
        if(transport.getHeader('ajaxClose'))
        {
            $('ajaxBackground').hide();
            $('ajaxContainer').hide();
        }
        else
        {
            if(target == 'ajaxContent')
            {
                $('ajaxBackground').show();
                $('ajaxContainer').show();
            }
            else
                $(target.strip()).show();
            Element.update($(target.strip()), response);
            ajaxInit();
        }
        // handle reload, css and js requests
        var headers = transport.getAllHeaders().split("\n");
        for(i = 0; i < headers.length; i++)
        {
            var header = headers[i].split(':');
            if(header[0].capitalize().startsWith('Ajaxreload_'))
            {
                var options = header[1].split('|');
                ajaxUrl(options[0], options[1]);
            }
        }
    }
}

function ajaxUrl(url, target)
{
    ajaxLoader(1);
    new Ajax.Request(url,
    {
        method:'get',
        onSuccess: function(transport)
        {
            ajaxTransport(transport, target);
            ajaxLoader(-1);
        },
        onFailure: function()
        {
            alert('Failed to receive AJAX response!');
            ajaxLoader(-1);
        }
    });
}

var ElAjaxBackground = new Element('div', { 'id': 'ajaxBackground' });
var ElAjaxClose = new Element('a', { 'id': 'ajaxClose', 'href': '#' });
var ElAjaxCloseIcon = new Element('div', { 'id': 'ajaxCloseIcon' });
var ElAjaxContainer = new Element('div', { 'id': 'ajaxContainer' });
var ElAjaxContent = new Element('div', { 'id': 'ajaxContent' });
var ElAjaxFooter = new Element('div', { 'id': 'ajaxFooter' });
var ElAjaxHeader = new Element('div', { 'id': 'ajaxHeader' });
var ElAjaxLoader = new Element('div', { 'id': 'ajaxLoader' });

ElAjaxBackground.hide();
ElAjaxContainer.hide();
ElAjaxLoader.hide();

ElAjaxClose.appendChild(ElAjaxCloseIcon);
ElAjaxClose.observe('click', function(event) { ajaxClose(); event.stop(); });

ElAjaxContainer.appendChild(ElAjaxClose);
ElAjaxContainer.appendChild(ElAjaxHeader);
ElAjaxContainer.appendChild(ElAjaxContent);
ElAjaxContainer.appendChild(ElAjaxFooter);

$('ajaxArea').appendChild(ElAjaxLoader);
$('ajaxArea').appendChild(ElAjaxBackground);
$('ajaxArea').appendChild(ElAjaxContainer);

ajaxInit();