﻿var uberAutoCompleteMembers;

function uberAutoComplete()
{
    this.index = undefined;
    this.targetId = undefined;
    this.topOffSet = undefined;
    this.cssClass = undefined;
    this.servicePath = undefined;
    this.timeout = undefined;
    this.precursors = undefined;

    this.addPrecursor = function(value)
    {
        if (this.precursors == undefined)
        {
            this.precursors = new Array();
        }

        this.precursors[this.precursors.length] = value;
    }

    this.attach = function()
    {
        document.getElementById(this.targetId).setAttribute('autocomplete', 'off');

        if (uberAutoCompleteMembers == undefined)
        {
            uberAutoCompleteMembers = new Array();
        }

        for (var i = 0; i <= uberAutoCompleteMembers.length && this.index == undefined; i++)
        {
            if (uberAutoCompleteMembers[i] == undefined)
            {
                this.index = i;
                uberAutoCompleteMembers[i] = new Object();
            }
        }

        this.id = Math.random().toString(16).substring(2);

        uberAutoCompleteMembers[this.index].id = this.id;
        uberAutoCompleteMembers[this.index].targetId = this.targetId;
        uberAutoCompleteMembers[this.index].topOffSet = this.topOffSet;
        uberAutoCompleteMembers[this.index].cssClass = this.cssClass;
        uberAutoCompleteMembers[this.index].servicePath = this.servicePath;
        uberAutoCompleteMembers[this.index].precursors = this.precursors;
        uberAutoCompleteMembers[this.index].timeout = this.timeout;

        var autoCompleteBox = document.createElement('div');
        autoCompleteBox.setAttribute('id', this.id);
        autoCompleteBox.className = this.cssClass;
        autoCompleteBox.style.display = 'none';
        autoCompleteBox.style.position = 'absolute';
        autoCompleteBox.style.width = document.getElementById(this.targetId).clientWidth + 'px';

        document.body.appendChild(autoCompleteBox);

        autoCompleteBox.style.left = uberGetElementPosition(this.targetId)[0] + 'px';
        autoCompleteBox.style.top = uberGetElementPosition(this.targetId)[1] + this.topOffSet + 'px';

        uberAddEvent(this.targetId, 'keyup', function()
        {
            uberAutoCompleteSendRequest(this);
        });

        //This is rubbish but so is IE handling of javascript
        if (this.index == 0)
        {
            uberAddEvent(this.targetId, 'blur', function()
            {
                uberAutoCompleteHide(0);
            });
        }
        else if (this.index == 1)
        {
            uberAddEvent(this.targetId, 'blur', function()
            {
                uberAutoCompleteHide(1);
            });
        }
        else if (this.index == 2)
        {
            uberAddEvent(this.targetId, 'blur', function()
            {
                uberAutoCompleteHide(2);
            });
        }
        else if (this.index == 3)
        {
            uberAddEvent(this.targetId, 'blur', function()
            {
                uberAutoCompleteHide(3);
            });
        }
        //////////////////////////////////////////////////
    }
}

function uberGetElementPosition(elementId)
{
    var left = 0;
    var top = 0;
    var element = document.getElementById(elementId);

    if (element.offsetParent)
    {
        do
        {
            left += element.offsetLeft;
            top += element.offsetTop;
        }
        while (element = element.offsetParent);
    }

    return [left, top];
}

function uberAutoCompleteSendRequest(element)
{
    var autoCompleteIndex = undefined;
    var targetControlId = undefined;
    var ajaxRequest = undefined;

    //Firefox
    if (element.getAttribute)
    {
        targetControlId = element.getAttribute('id');
    }
    //IE
    else
    {
        targetControlId = document.activeElement.getAttribute('id');
    }

    for (var i = 0; i < uberAutoCompleteMembers.length && autoCompleteIndex == undefined; i++)
    {
        if (uberAutoCompleteMembers[i].targetId == targetControlId)
        {
            autoCompleteIndex = i;
        }
    }

    if (window.XMLHttpRequest)
    {
        ajaxRequest = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
        ajaxRequest = new ActiveXObject('Microsoft.XMLHTTP');
    }

    ajaxRequest.onreadystatechange = function()
    {
        if (ajaxRequest.readyState == 4 && ajaxRequest.status == 200)
        {
            var output = new String();
            var entry = new String();
            var currentPosition = 0;
            var currentEnd = 0;

            output += '<ul>';

            while (currentPosition != -1)
            {
                currentEnd = ajaxRequest.responseText.indexOf('|', currentPosition + 1);

                if (currentEnd == -1)
                {
                    currentEnd = ajaxRequest.responseText.length;
                }

                entry = ajaxRequest.responseText.substring(currentPosition, currentEnd);

                if (entry != '')
                {
                    output += '<li onclick="uberAutoCompleteSelect(' + autoCompleteIndex + ', this.innerHTML);">' + ajaxRequest.responseText.substring(currentPosition, currentEnd).replace('|', '') + '</li>';
                }

                currentPosition = ajaxRequest.responseText.indexOf('|', currentPosition + 1);
            }

            output += '</ul>';

            document.getElementById(uberAutoCompleteMembers[autoCompleteIndex].id).innerHTML = output;
            document.getElementById(uberAutoCompleteMembers[autoCompleteIndex].id).style.display = 'block';
        }
    };

    var servicePath = uberAutoCompleteMembers[autoCompleteIndex].servicePath;
    servicePath = servicePath + '?cacheBuster=' + new Date();
    servicePath = servicePath + '&' + uberAutoCompleteMembers[autoCompleteIndex].targetId + '=' + document.getElementById(uberAutoCompleteMembers[autoCompleteIndex].targetId).value;

    if (uberAutoCompleteMembers[autoCompleteIndex].precursors != undefined)
    {
        for (var i = 0; i < uberAutoCompleteMembers[autoCompleteIndex].precursors.length; i++)
        {
            servicePath = servicePath + '&' + uberAutoCompleteMembers[autoCompleteIndex].precursors[i] + '=' + document.getElementById(uberAutoCompleteMembers[autoCompleteIndex].precursors[i]).value;
        }
    }

    ajaxRequest.open('GET', servicePath, true);
    ajaxRequest.send(null);
}

function uberAutoCompleteSelect(autoCompleteIndex, value)
{
    uberAutoCompleteHide(autoCompleteIndex);
    document.getElementById(uberAutoCompleteMembers[autoCompleteIndex].targetId).value = value.replace(/(<([^>]+)>)/ig,"");
}

function uberAutoCompleteHide(autoCompleteIndex)
{
    setTimeout('uberAutoCompleteHider(' + autoCompleteIndex + ')', 400);
}

function uberAutoCompleteHider(autoCompleteIndex)
{
    document.getElementById(uberAutoCompleteMembers[autoCompleteIndex].id).style.display = 'none';
}

function uberAddEvent(elementId, eventName, method)
{
    if (document.getElementById(elementId).addEventListener)
    {
        document.getElementById(elementId).addEventListener(eventName, method, false);
    }
    else if (document.getElementById(elementId).attachEvent)
    {
        document.getElementById(elementId).attachEvent('on' + eventName, method);
    }
}