  ajaxBox = {
            /* ajaxBox global variables */
            settings: ['ajaxService','valuefieldid','wordfieldid','multiple','multiSelectListSeparator','help','minCharsBeforeSearch','resultPageSize'],
            field: null,
            activeIndex:null,
                        
            init: function ()
            {
                $('<input type="button" value="=" class="synonymButton"/>').insertAfter('.ajaxBox');        
                $('.ajaxBox').bind('keyup.ajaxBox', function (e) {
                    ajaxBox.field = e.target;
                    var keyCode = e.which;
                    ajaxBox.keyUpHandler(keyCode);  
                }).bind('click', function ( e )
                {
                    ajaxBox.field = e.target;
                    if ( ( ajaxBox.field.value.length >= ajaxBox.field.settings.minCharsBeforeSearch && $('ajaxOption').length == 0 ) )
                    {
                        ajaxBox.getOptions();
                    }                        
                }).each( function ( a ) {
                    var settings = {};
                    //* set default values ( overrided if defined in html )
                    settings.minCharsBeforeSearch = 3;
                    settings.resultPageSize = 10;
                    //* check for overriding values...
                    for ( var s = 0; s < ajaxBox.settings.length; s++ )
                    {
                        if ( this.getAttribute(ajaxBox.settings[s]) != null )
                        {
                            settings[ajaxBox.settings[s]] = this.getAttribute(ajaxBox.settings[s]);
                        }
                    }
                    //* default values that cannot be overrided 
                    settings.ajaxIndex = a;
                    settings.selection = {};
                    settings.selectedOption = -1;
                    this.settings = settings;
                    settings = null;
                    if($('#'+this.settings.wordfieldid).length > 0 )
                    {
                        this.value = $('#'+this.settings.wordfieldid).get(0).value;
                    }
                });
            },
            
            refreshSelection: function ( selectedOption, doMultiSelect )
            {
                var resultsBeforePageStart = $('.hideBefore').length + $('.multiSelected').length;
                

                if ( selectedOption >= $('.ajaxOption').length )
                    selectedOption = $('.ajaxOption').length -1 ;
                
                if ( selectedOption < 0 )
                    selectedOption = 0;

                ajaxBox.field.settings.selectedOption = selectedOption;
                                   
                $('.ajaxOption').each( function ( i )
                {
                    $(this).removeClass('selected').removeClass('nextResult').removeClass('prevResult');      
                    if ( i == ajaxBox.field.settings.selectedOption )
                    {
                        if ( $(this).next().hasClass('hideAfter') )
                        {
                            $(this).next().removeClass('hideAfter');
                            $($('.ajaxOption').get(resultsBeforePageStart)).addClass('hideBefore');
                        } 
                        if ( $(this).prev().hasClass('hideBefore') )
                        {
                            $(this).prev().removeClass('hideBefore');
                        } 
                        ajaxBox.field.value = $(this).addClass('selected').text();   
                        if ( $(this).hasClass('hasSynonyms') == true )
                        {
                            $(ajaxBox.field).next().next().css('display','inline');
                        }
                        else
                        {
                            $(ajaxBox.field).next().next().css('display','none');
                        }   
                    }
                })
                var lastItem = $('.hideBefore').length + $('.multiSelected').length + parseInt( ajaxBox.field.settings.resultPageSize ) - 1;
                $( $('.ajaxOption').get( lastItem ) ).nextAll().addClass('hideAfter');
                if ( $('.hideBefore').length > 0 )
                {
                    $( $('.ajaxOption').get( $('.hideBefore').length + $('.multiSelected').length )).addClass('prevResult');
                }
                if ( $('.hideAfter').length > 0 )
                {
                    $( $('.hideAfter').get(0)).prev().addClass('nextResult');
                }
            },
            
            keyUpHandler: function ( keyCode )
            {                
                var selectedOption = parseInt( ajaxBox.field.settings.selectedOption );
                switch ( keyCode )
                {
                    case 13:
                    {
                        ajaxBox.select();
                        //* Hämeenlinnan formin submit */
                        //$('#ctl00_FullRegion_MainAndRightRegion_MainRegion_ctl00_SearchButton2').click();
						$('#searchcriteria input.inputBtnSearch').click();
                        return false;
                    };break;
                    case 27:
                    {
                        ajaxBox.close();
                    };break;
                    case 40:
                    {
                        selectedOption++;                      
                        ajaxBox.refreshSelection(selectedOption);
                    };break;
                    case 38:
                    {
                        selectedOption--;
                        ajaxBox.refreshSelection(selectedOption);
                    };break;
                    default:
                    {
                        if ( ajaxBox.field.value.length >= ajaxBox.field.settings.minCharsBeforeSearch )
                        {
                            ajaxBox.getOptions();
                        }
                        else
                        {
                            ajaxBox.close();
                        }
                    };break;
                }
            },
            
            select: function ()
            {
                if ( $('.ajaxPopUp').find('.selected').length > 0 )
                {
                    var hideMenu = false;
                    
                    if ( ajaxBox.field.settings.multiple != 'true' )
                    {
                        ajaxBox.field.settings.selection = {};
                    }
                    
                    var menuSelection = $('.ajaxPopUp').find('.selected').get(0);            
                    if ( $(menuSelection).hasClass('multiSelected') == true )
                    { 
                        var newSelection = {};
                        var removeValue = menuSelection.getAttribute('value');
                        for ( var r in ajaxBox.field.settings.selection )
                        {
                            if ( r != removeValue )
                            {
                                newSelection[r] = ajaxBox.field.settings.selection[r];
                            }
                        }
                        ajaxBox.field.value = '';
                        ajaxBox.field.title = '';
                        ajaxBox.field.settings.selection = newSelection;
                        hideMenu = true;
                        $(menuSelection).removeClass('multiSelected').removeClass('selected');
                    } 
                    else if ( $(menuSelection).hasClass('isForbidden') == false )
                    {
                        var valueKey = menuSelection.getAttribute('value');
                        if ( typeof( ajaxBox.field.settings.selection[valueKey] ) == 'undefined' )
                        {
                            var newValue = {};
                            newValue.value = valueKey;
                            newValue.name = $(menuSelection).text();
                            ajaxBox.field.settings.selection[valueKey] = newValue;
                        } 
                        hideMenu = true;
                    }
                    else
                    {
                        ajaxBox.field.value = '';
                    }
                    
                    if ( hideMenu == true )
                    {
                        ajaxBox.close();  
                    }
                    ajaxBox.setValue();
                } 
                else
                {
                    ajaxBox.close();
                } 
            },
            
            setValue: function ()
            {
                var selectedValues = [];
                var separator = ',';             
                if ( typeof( ajaxBox.field.settings.multiSelectListSeparator ) != 'undefined' )
                {
                    separator = ajaxBox.field.settings.multiSelectListSeparator;
                }
                
                for ( var s in ajaxBox.field.settings.selection )
                {
                    selectedValues[selectedValues.length] = ajaxBox.field.settings.selection[s].value;
                }
                if ( $('#'+ajaxBox.field.settings.valuefieldid).length == 1 )
                {
                    $('#'+ajaxBox.field.settings.valuefieldid).get(0).value = selectedValues.join(separator);
                }
                else
                {
                    alert('('+ajaxBox.field.settings.valuefieldid+') ajax fields found:'+$('#'+ajaxBox.field.settings.valuefieldid).length)
                }
                if($('#'+ajaxBox.field.settings.wordfieldid).length > 0 )
                {
                    $('#'+ajaxBox.field.settings.wordfieldid).get(0).value = ajaxBox.field.value
                }
                else
                {
                    alert(ajaxBox.field.settings.wordfieldid +' ei löydy !');
                }
                
                return true;
            },
            
            show: function ( popUpHTML )
            {
                if ( ajaxBox.activeIndex != ajaxBox.field.settings.ajaxIndex )
                {
                    ajaxBox.close();
                }
                ajaxBox.activeIndex = ajaxBox.field.settings.ajaxIndex;
                var ajaxBoxPosition = $(ajaxBox.field).GetAbsolutePositions().get(0).absolutePosition;
                if ( $('.ajaxPopUp').length == 0 )
                {
                    $('<div class="ajaxPopUp" style="top:'+ parseInt( ajaxBoxPosition.y + ajaxBox.field.clientHeight + 3 ) +'px;left:'+ajaxBoxPosition.x+'px;width:'+ajaxBox.field.clientWidth+'px">'+popUpHTML+'</div>').insertAfter(ajaxBox.field).show('slow').get(0);         
                }
                else
                {
                    $('.ajaxPopUp').html(popUpHTML).get(0);
                } 
                ajaxBox.field.settings.selectedOption = $('.multiSelected').length - 1;
                ajaxBox.field.title = ajaxBox.field.settings.help;
                ajaxBox.bindMenuActions();  
            },
            
            close: function ()
            {
                $('.ajaxPopUp').hide('slow', function () { $('.ajaxPopUp').remove() });
                ajaxBox.field.settings.selectedOption = -1;
                ajaxBox.field.title = '';
            },
            
            bindMenuActions: function ()
            {
                $('.ajaxOption').each( function ( i ){
                    $(this).get(0).ajaxBox = ajaxBox.field;
                    this.ajaxIndex = i;
                }).hover( 
                    function ( e ) { 
                        ajaxBox.refreshSelection( e.target.ajaxIndex );
                    },
                    function ( e )
                    {
                        $(e.target).removeClass('selected');    
                    }
                ).click( function ( e )
                {
                    ajaxBox.select();              
                } ); 
            },
            
            getOptions: function ()
            {  
                var sendData = 'CategoryID=&BeginsWith='+ajaxBox.field.value;
                //var sendData ='<?xml version="1.0" encoding="utf-8"?>
                //var sendData = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetMatches xmlns="http://hextra/webservices/subject"><CategoryID><![CDATA[]]</CategoryID><BeginsWith><![CDATA['+ajaxBox.field.value+']]></BeginsWith></GetMatches></soap:Body></soap:Envelope>'
                
                var ajaxUrl = ''+ajaxBox.field.settings.ajaxService;                            
                $.ajax({   
                    type:       'POST',   
                    url:        ajaxUrl,   
                    dataType:   "xml",   
                    data:       sendData,      
                    success: function(xml) {   
                        ajaxBox.renderMenu( xml );
                    },   
                    error: function( XMLHttpRequest, textStatus, errorThrown ) {   
                        alert('ERROR: SOAP call failed! reason: ' + textStatus + '--' + XMLHttpRequest.responseText + '--' + errorThrown);
                    }  
                })
            },
            
            getXML: function ( raxXML )
            {
                var xmlData = null;
                try //Internet Explorer
                {
                  xmlData=new ActiveXObject("Microsoft.XMLDOM");
                  xmlData.async="false";
                  xmlData.loadXML(raxXML);
                }
                catch(e)
                {
                    try //Firefox, Mozilla, Opera, etc.
                    {
                        parser=new DOMParser();
                        xmlData=parser.parseFromString(raxXML,"text/xml");
                    }
                    catch(e) 
                    {
                        alert(e.message)
                    };
                }
                return xmlData;
            },
            
            renderMenu: function ( ajaxXML )
            {
                var ajaxXML = ajaxBox.getXML(ajaxXML.getElementsByTagName('string')[0].childNodes[0].nodeValue);
                var optionsHTML = [];
                var suggestions = ajaxXML.getElementsByTagName('Result'); 
                var lastLine = parseInt( ajaxBox.field.settings.firstLine ) + parseInt( ajaxBox.field.settings.resultPageSize )
                var linesRendered = 0;
                if ( ajaxBox.field.settings.multiple == 'true' )
                {
                    for ( var s in ajaxBox.field.settings.selection )
                    {
                        optionsHTML[optionsHTML.length] = '<div class="ajaxOption multiSelected" value="'+ajaxBox.field.settings.selection[s].value+'">'+ajaxBox.field.settings.selection[s].name+'</div>'
                        ajaxBox.field.settings.selectedOption++;
                    }
                }
                               
                for ( var s = 0; s < suggestions.length; s++ )
                {
                    var suggestionText = suggestions[s].getElementsByTagName('Name')[0].childNodes[0].nodeValue;
                    var suggestionValue = suggestions[s].getElementsByTagName('Value')[0].childNodes[0].nodeValue;
                    var additionalClasses = '';
                    //* Don't re-render selected values !*/
                    if ( typeof( ajaxBox.field.settings.selection[suggestionValue] ) == 'undefined'  )
                    {
                        if ( suggestions[s].parentNode.tagName == 'Children')
                        {
                            additionalClasses += ' isChild';    
                        }
                        if ( suggestions[s].getAttribute('isforbidden') == 'true' )
                        {
                            additionalClasses += ' isForbidden';   
                        }                    
                        if ( suggestions[s].getAttribute('replacingterm') == "true" )
                        {
                            additionalClasses += ' replacingTerm'; 
                        }
                        if ( suggestions[s].getAttribute('hassynonyms') != null )
                        {
                            additionalClasses += ' hasSynonyms';
                        }
                        if ( linesRendered == ajaxBox.field.settings.resultPageSize - 1 )
                        {
                            additionalClasses = ' nextResult'
                        }
                        if ( linesRendered >= ajaxBox.field.settings.resultPageSize )
                        {
                            additionalClasses += ' hideAfter';    
                        }
                        if ( linesRendered < ajaxBox.field.settings.firstLine )
                        {
                            additionalClasses += ' hideBefore';
                        }
                        linesRendered++;
                        optionsHTML[optionsHTML.length] = '<div class="ajaxOption'+additionalClasses+'" value="'+suggestionValue+'">'+suggestionText+'</div>'
                        
                    }
                }
                optionsHTML = optionsHTML.join('');
                ajaxBox.show( optionsHTML );
                return optionsHTML;
            }
        }
        
        
                
        // jQuery extension for calculating absolute client positions         
        $.fn.GetAbsolutePositions = function ()
        {
            return this.each( function ()
            {
               var current = this;
               var aX = 0;
               var aY = 0;

               aX = parseInt(document.body.offsetLeft);
               aY = parseInt(document.body.offsetTop);
               
               while( current.id != 'container' )
               {
                    aX += parseInt( current.offsetLeft );
                    aY += parseInt( current.offsetTop );
                    current = current.offsetParent;  
                    if ( typeof( current ) == 'undefined' || current.tagName.toLowerCase() == 'html' )
                    {
                        current = document.body;   
                        break;    
                    }         
               }

               this.absolutePosition = { x:aX, y:aY };
               current = null;
            })
        }
        
// startup code here
$(document).ready( function () {
    ajaxBox.init();
})

