document.write("<script src='http://fahrplan.avv.de/components/HSSC/js/valid.php'></script>");

var Autocomplete = function() {
    return function(elements, emptyDefaults, basepath, onQueryCallback, onDataCallback, handler, mobile) {

        var isMobile = mobile;
        
        if(elements.textfield.length==0) return;
        
        var element = elements.textfield;
        
        var gkz_field = elements.gkz;
        var type_field = elements.type;
        var stop_id_field = elements.station_id;
        var types = elements.types;

        var me = this;
        var resultDefaults = $('<div class="autocompleteDefaults">Häufige Auswahl</div>');
        var resultIhreSuche = $('<div class="autocompleteDefaults">Ihre Suche</div>');
        var resultContainer = $('<div style=""></div>');
        var resultElement = $('<ul class="autocomplete"></ul>');
        var selectionIndex = -1;
        var resultData;
        var overResultList = false;

        var last_request = 0;
        var request_pending = false;
        var queryDelay = 300;

        var previousContent = 'xcvy';

        var requestSequence = 0;
        var responseSequence = 0;

        var received_gkz = 0;

        var itemsInList = [];

        resultContainer.append(resultDefaults);
        resultContainer.append(resultIhreSuche);
        resultContainer.append(resultElement);


        if (element.val() == '' || $.trim(element.val()) == '') {
            showLabel();
        }

        element.attr('autocomplete', 'off');

        this.uniqueID = ++Autocomplete.COUNTER;
        Autocomplete.INSTANCES[this.uniqueID] = this;

        resultElement.bind('mouseover', function() {
            overResultList = true;
        }).bind('mouseout', function() {
            overResultList = false;
        });

        function showLabel() {
            element.addClass('label');
            element.val(elements.label);
        }

        function hideLabel() {
            element.removeClass('label');
            element.val('');
        }

        element.bind('focus', function() {
            element.focused = true;
            if (element.val() == elements.label) {
                hideLabel();
            }
        }).bind('blur', function() {
	    
		if (!overResultList)
		    resultContainer.hide();
		element.focused = false;
	    
	    
            if (element && element['val'] && ($.trim(element.val())) == '') {
                showLabel();
            }
        });

        function registerEvents() {
            element.bind('keydown', function(e) {
                switch (e.keyCode) {
                    //case 9:  // key tab
                    //    submitSelection();
                    //    break;
                    case 13: // key enter
                        if (!resultElement.is(':visible'))
                            break; 
                        submitSelection();
                        e.preventDefault();
                        break;
                }


            });


            element.bind('keyup', function(e) {
                function doRequest() {
                        unsetHiddenFields();
                        if (element.attr('value') == '' && elements.mode == 'city') {
                            me.setData([]);
                            resultContainer.hide();
                        }
                        else {
                            if (previousContent != element.attr('value')) {
                                fireRequest(element.attr('value'));
                            }
                            else if (resultData) {
                                me.setData(resultData);
                            }

                        }
                        previousContent = element.attr('value');
                }

                switch (e.keyCode) {
                    case 27: // key escape
                        resultContainer.hide();
                        break;
                    case 37:
                    case 39:
                        break;
                    case 38: // key up
                        selectPrevious();
                        break;
                    case 40: // key down
                        if (resultElement.is(':visible'))
                            selectNext();
                        else
                            doRequest();
                        break;
                    case 13: // key enter
                        submitSelection();
                        e.preventDefault();
                        break;

                    default:
                        doRequest();
                }

            });

            element.bind('focus', function(e) {
		if(isMobile) $(resultContainer).show();
		

                if (elements.mode == 'city' && emptyDefaults && !element.attr('value')) {
                    me.setData(emptyDefaults);
                    selectFirst();
                }
                else if (elements.mode == 'stop' &&!element.attr('value'))
                    fireRequest('');
            });
        }

        function selectFirst() {
            if (!resultElement.is(':visible'))
                return;

            selectionIndex = 0;

            updateSelection('down');
        }

        function selectNext() {
            if (!resultElement.is(':visible'))
                return;
        
            if (selectionIndex == NaN || selectionIndex == undefined)
                selectionIndex = -1;

            selectionIndex = ((selectionIndex + 1) % getElementCount());

            updateSelection('down');
        }

        function selectPrevious() {
            if (!resultElement.is(':visible'))
                return;

            if (!selectionIndex)
                selectionIndex = -1;

            if (selectionIndex == 0 || selectionIndex == -1)
                selectionIndex = getElementCount() - 1;
            else
                selectionIndex -= 1;

            updateSelection('up');
        }

        function updateSelection(direction, index) {

            if (index == undefined || index == NaN)
                index = selectionIndex;

            for(var i = 0; i < resultElement.attr('childNodes').length; i++) {
                if (i == index) {
                    $(resultElement.attr('childNodes')[i]).addClass('selected');

                    if ($(resultElement.attr('childNodes')[i]).position().top < 0) {
                        resultElement.scrollTop(
                            resultElement.scrollTop() + $(resultElement.attr('childNodes')[i]).position().top
                        );
                    }

                    if ($(resultElement.attr('childNodes')[i]).position().top + $(resultElement.attr('childNodes')[i]).height() >= resultElement.height()) {
                        resultElement.scrollTop(
                            resultElement.scrollTop() + $(resultElement.attr('childNodes')[i]).position().top - resultElement.height() + $(resultElement.attr('childNodes')[i]).height()
                        );

                    }

                }
                else{
                    $(resultElement.attr('childNodes')[i]).removeClass('selected');
                }
            }
            var position = element.offset();
            $(resultContainer).css('left', position.left + 'px');
        }

        function unsetHiddenFields() {


            if (elements.resetValues) {
                $(elements.resetValues).each(function(i) {
                    this.val('');
                });
            }


            if (gkz_field) {
                gkz_field.attr('value', '');
            }
            if (stop_id_field) {
                stop_id_field.attr('value', '');
            }
            if (type_field) {
                type_field.attr('value', '');
            }
        }


        function setGKZ(gkz, id) {
            if (gkz_field) {
                gkz_field.attr('value', gkz + ':' + id);
            }
        }

        function setStopId(num) {
            if (stop_id_field) {
                stop_id_field.attr('value', num);
            }
        }

        function setType(type) {
            if (type_field) {
                type_field.attr('value', type);
            }
        }

        function submitSelection(index) {

            if (index == undefined)
                index = selectionIndex;

            if ($(resultElement) && $(resultElement).is(':visible') && resultData && resultData[index]) {
                element.attr('value', resultData[index].fullname);

                if (resultData[index].gkz && resultData[index].ortsid !== null && resultData[index].ortsid !== undefined) {
                    setGKZ(resultData[index].gkz, resultData[index].ortsid);
                }

                if (resultData[index].id) {
                    setStopId(resultData[index].id);
                }

                if (resultData[index].type) {
                    setType(resultData[index].type);
                }
            }
            //if(!isMobile)
		$(resultContainer).hide();
            element.removeClass('label');
        }

        function getElementCount() {
            if (resultElement && resultElement.attr('childNodes')) {
                return resultElement.attr('childNodes').length;
            }
            return 0;
        }

        function fireRequest(query, callback) {

            var current_time = new Date().getTime();

            if (current_time - last_request < queryDelay) {
                if (request_pending) {
                    window.clearTimeout(request_pending);
                }

                request_pending = window.setTimeout(
                    function (q) {
                        return function() {
                            fireRequest(q);
                        };
                    }(query),
                    queryDelay
                );

                return;
            }

            if (request_pending) {
                window.clearTimeout(request_pending);
            }

            last_request = current_time;
            request_pending = false;

            var additionalQueryParams = '';

            if (elements.mode == 'stop' && !element.val())
                additionalQueryParams = '&rpc[hssc][mode]=important';
            else
                additionalQueryParams = '&rpc[hssc][mode]=' + elements.mode;

            try {
                if (onQueryCallback) {
                    var additionalParams = onQueryCallback();
                    for(var i in additionalParams) {
                        additionalQueryParams += '&rpc[hssc][' + i + ']=' + encodeURIComponent(additionalParams[i]);
                    }
                }
            }
            catch (e) {
		
                return;
            }

            if (received_gkz)
                additionalQueryParams += '&rpc[hssc][received_city_gkz]=' + received_gkz;

            //var include_delfi = elements.include_delfi ? ($(elements.include_delfi).attr('checked') == false) : false;
            var include_delfi = $(elements.include_delfi).is(':checked');
            //console.log(include_delfi);

            if (handler && handler == 'jsonp') {
				$.getJSON(basepath + '&rpc[hssc][instance]=' + me.uniqueID + '&rpc[hssc][query]=' +query +  additionalQueryParams + '&rpc[hssc][include_delfi]=' + include_delfi + '&rpc[hssc][types]=' + types+'&callback=?',
				   function(msg) {
				       
								me.setData(msg.results);
								if (msg.meta) {
									received_gkz = msg.meta;
								}
								selectFirst();

								if (typeof callback == 'function')
									callback();
						   }
						);
            }
            else {
                $.ajax({
                   'type': "GET",
                   'url' : basepath + '&rpc[hssc][instance]=' + me.uniqueID + '&rpc[hssc][query]=' +query +  additionalQueryParams + '&rpc[hssc][include_delfi]=' + include_delfi + '&rpc[hssc][types]=' + types,
                   'data': '',
                   'dataType': 'json',
                   'success' : function()  {
                       var rs = ++requestSequence;
                       return function(msg) {
                            if (rs <= responseSequence || !msg) {
                                return;
                            }
                            responseSequence = rs;

			    if(elements.mode=='stop') {
				if(elements.station_id.attr('id').indexOf('departure')!=-1) {
				    var mygkz = $('#departure_city_gkz').val();
				    if(mygkz.indexOf(':')!=-1) mygkz = mygkz.substring(0,mygkz.indexOf(':'));

				    var res = new Array();
				    for(var i = 0; i < acdeps.length; i++) {
					if(acdeps[i].gkz == mygkz) {
					    var S = acdeps[i];
					    S.name = S.station;
					    S.type = S.stype;
					    S.fullname = S.station;
					    res[res.length] = S;
					}
				    }
				    for(var i = 0; i < msg.results.length; i++) {
					var found = false;
					for(var j=0;j<res.length;j++) {
					    if(res[j].id == msg.results[i].id) {
						found = true;
						break;
					    }
					}
					if(!found) {
					    res[res.length] = msg.results[i];
					}
				    }
				    msg.results = res;
				} else if(elements.station_id.attr('id').indexOf('arrival')!=-1) {
				    var mygkz = $('#arrival_city_gkz').val();
				    if(mygkz.indexOf(':')!=-1) mygkz = mygkz.substring(0,mygkz.indexOf(':'));

				    var res = new Array();
				    for(var i = 0; i < acdeps.length; i++) {
					if(acdeps[i].gkz == mygkz) {
					    var S = acdeps[i];
					    S.name = S.station;
					    S.type = S.stype;
					    S.fullname = S.station;
					    res[res.length] = S;
					}
				    }
				    for(var i = 0; i < msg.results.length; i++) {
					var found = false;
					for(var j=0;j<res.length;j++) {
					    if(res[j].id == msg.results[i].id) {
						found = true;
						break;
					    }
					}
					if(!found) {
					    res[res.length] = msg.results[i];
					}
				    }
				    msg.results = res;
				}
			    }

                            me.setData(msg.results);
                            if (msg.meta) {
                                received_gkz = msg.meta;
                            }
                            selectFirst();

                            if (typeof callback == 'function')
                                callback();
                       }
                   }()
                });
            }
        }

        this.reinit = function() {
            if (element.val() == '' || element.val() == elements.label) {
                showLabel();
            }
            else if(element.val() != elements.label) {
                fireRequest(element.val(), function() {
                    resultContainer.hide();
                    for(var i in resultData) {
                        if (resultData[i].fullname == element.val()) {
                            selectionIndex = i;
                            updateSelection('', i);
                            break;
                        }
                    }
                });


            }
        }

        this.getCurrent = function() {
            if (resultData && resultData[selectionIndex])
                return resultData[selectionIndex];
            return {};
        }

        this.beforeSubmitCallback = function() {
            if (element.val() == elements.label)
                element.val('');
        }

        this.setData = function (data) {
            selectionIndex = -1;


            /*if(isMobile) {
                if(data.length>5) {
                    var data2 = new Object();
                    for(i=0;i<5;i++) {
                        data2[i] = data[i];
                    }
                    data = data2;
                }
            }*/


            if(data==emptyDefaults || element.val()=='' ) {
                resultDefaults.show();
                resultIhreSuche.hide();
            } else {
                resultDefaults.hide();
                resultIhreSuche.show();
            }

            if (onDataCallback) {
                onDataCallback(data);
            }

            if (!data || (data instanceof Array && data.length == 0)) {
                resultContainer.hide();
                return;
            }

            if (!resultElement.parentNode) {
                if(isMobile) {
                    $('#'+isMobile).show();
                    $('#'+isMobile).append(resultContainer);
                } else {
                    $('body').append(resultContainer);
                }
            }

            if (element.focused) {
                $(resultContainer).show();
            }

            resultData = data;

            resultElement.empty();

            var position = element.offset();
            //alert(position.left);

            $(resultContainer)
                .css('margin', 0)
                .css('padding', 0);
            if(!isMobile) {
                $(resultContainer).css('position', 'absolute')
                    .css('top', position.top + element.attr('offsetHeight') + 'px')
                    .css('left', position.left + 'px')
                    .css('minWidth', element.attr('offsetWidth') + 'px');
            }

            $(resultElement)
                .css('margin', 0)
                .css('padding', 0)
                .css('minWidth', element.attr('offsetWidth') + 'px');

            var itemsInList = [];

            var alreadyStoredItems = [];
            var offset = 0;
            var countOut = 0;

            for(var i = 0; i < emptyDefaults.length; i++) {

                var edElement = emptyDefaults[i];
                //console.log(edElement.name);
                if (edElement.fullname.toLowerCase().substring(0, element.val().length) != element.val().toLowerCase()) {
                    continue;
                }

                alreadyStoredItems[edElement.fullname] = true;
                itemsInList.push(edElement);

                if(isMobile) if(countOut++>5) break;
                
                $(resultElement).append(
                    $('<li class="'+edElement.type+'"></li>')
                    .append(edElement.fullname) //+ ' [' + (1-data[i].ratio) + ']')
                    .bind('click', function(index) {
                        return function() {
                            //dirty
                            selectionIndex = index;
                            overResultList = false;
                            submitSelection(index);
                            if(!isMobile) element.focus();
                        };
                    }(offset))
                    .bind('mouseover', function(index) {
                        return function() {
                            updateSelection('up', index);
                        };
                    }(offset))
                    .bind('mouseout', function(index) {
                        return function() {
                            updateSelection('up', -1);
                        };
                    }(offset))
                );
                offset++;
            }

            var offset2 = 0;
            
            for(var i = 0; i < data.length - offset; i++) {

                if(isMobile) if(countOut++>5) break;
                
                if (alreadyStoredItems[data[i].fullname])
                    continue;
                itemsInList.push(data[i]);

                if(data[i].type=='address') prefix = "[Adresse] ";
                else if(data[i].type=='poi') prefix = "[POI] ";
                else if(data[i].type=='stop') prefix = "[Haltestelle] ";
                else prefix = "";

                $(resultElement).append(
                    $('<li class="'+data[i].type+'"></li>')
                    .append('<span class="acprefix" style="font-size:7pt;">'+prefix+'</span>'+data[i].fullname) //+ ' [' + (1-data[i].ratio) + ']')
                    .bind('click', function(index) {
                        return function() {
                            //dirty
                            selectionIndex = index;
                            overResultList = false;
                            submitSelection(index);
                            if(!isMobile) element.focus();
                        };
                    }(offset2 + offset))
                    .bind('mouseover', function(index) {
                        return function() {
                            updateSelection('up', index);
                        };
                    }(offset2 + offset))
                    .bind('mouseout', function(index) {
                        return function() {
                            updateSelection('up', -1);
                        };
                    }(offset2 + offset))
                );
                offset2++;

                

            }
            resultData = itemsInList;
        }


        registerEvents();

        if (gkz_field && gkz_field.val()) {
            var parts = gkz_field.val().split(':');
            setGKZ(parts[0], parts[1]);
        }

        if (type_field && type_field.val()) {
            setType(type_field.val());
        }

        if (stop_id_field && stop_id_field.val()) {
            setStopId(stop_id_field.val());
        }

    };

}();

Autocomplete.COUNTER = 0;
Autocomplete.INSTANCES = [];

Autocomplete.$ac = function (instance, result) {
    if (Autocomplete.INSTANCES[instance]) {
        if ($('#ac_src_' + instance))
            $('#ac_src_' + instance).remove();


        Autocomplete.INSTANCES[instance].setData(result);
    }
}
