var sugFocusId = -1;
var mdvSug = {};

mdvSug.config = {

    'delay': 250,                       // timeout for request, in ms
    'sendOdvSuggestMin': 3,             // minimum number of chars
    'url': 'XSLT_STOPFINDER_REQUEST',   // switch this to XML_ for Zweifeld
    'submit': false,                    // submit form on entry select
    'sf_params_shared': {
        'language': 'de',
        'useHouseNumberList': '1',
        'stateless': '1'
    },

    'sf_params_any_enabled': {
        'locationServerActive': '1',
        'outputFormat': 'JSON',
        'anyObjFilter_sf': '0',
        'anyMaxSizeHitList': '50',
        'type_sf': 'any',
        'reducedAnyWithoutAddressObjFilter_sf': '103',
        'reducedAnyPostcodeObjFilter_sf': '64',
        'reducedAnyTooManyObjFilter_sf': '2'
    },

    'sf_params_no_any': {
        'locationServerActive': '0'
    }
};

mdvSug.currentElem = null;          // takes an element reference to input field
mdvSug.currentInput = '';           // 'name' or 'place'
mdvSug.timer = null; 
mdvSug.checkText = '';
mdvSug.opt = ['<div id="sug_', 
              '-iterator-', 
              '" class=""><a href="javascript:mdvSug.submit_entry(\'', 
              '-id-', 
              '\',\'',
              '-txt_only-', 
              '\',\'', 
              '-usage-', 
              '\')" class="sugFo">', 
              '-txt-', 
              '</a></div>'];        // array with option str boilerplate
              
mdvSug.imgTag = '<img src="img/suggest/#IMG#"/>';

mdvSug.trigger = function (event, elem) {

    // 38 = ARROW UP
    // 40 = ARROW DOWN
    // 27 = ESC
    
    if (event.keyCode === 38 || event.keyCode === 40 || event.keyCode === 27) {
        return false;
    }
    
    if (this.timer) {
        window.clearTimeout(this.timer);
        this.timer = null;    
    }
    
    var value = elem.value,
        usage = elem.name.split('_').pop();

    this.checkText = value;
    this.currentElem = elem;
    this.currentInput = elem.name.split('_').shift();
    
    this.timer = window.setTimeout(
                    function () {
                        if (mdvSug.checkText !== value) {
                            return false;
                        }
                        mdvSug.send(value, usage);
                    }, mdvSug.config.delay);
};


mdvSug.send = function (value, usage) {
    
    //jQuery('#' + this.currentInput + 'Info_' + usage).val('invalid');
    
    if (value.length < this.config.sendOdvSuggestMin) {

        // remove if present
        jQuery('#odvOverlay').remove();
        return false;
    }
    
    var i, f;
    for (i=0; i<document.forms.length; i+=1) {
        if (document.forms[i].elements['name_'+usage] !== undefined) {
            f = document.forms[i];
            break;
        }
    } 
    
    var k, loc_server_active = jQuery('[name=locationServerActive]', f).val(),
        params = this.config.sf_params_shared,
        i_type = this.currentInput,
        other_field = 'place';

    // -------------------------------
    // ----- With location server ----
    // -------------------------------  
    if (loc_server_active === '1') {
        for (k in this.config.sf_params_any_enabled) {
            params[k] = this.config.sf_params_any_enabled[k];
        }

        params.anyObjFilter_sf = jQuery('input:radio[name=anyObjFilter_' + usage + ']:checked', f).val();
        params.name_sf = value;


    // -------------------------------
    // ----- No location server ------
    // -------------------------------  
    } else {

        for (k in this.config.sf_params_no_any) {
            params[k] = this.config.sf_params_no_any[k];
        }

        // place input
        if (i_type !== 'name') {
            other_field = 'name';
        }

        params[i_type + '_sf'] = value;
        params[other_field + '_sf'] = jQuery('[name=' + other_field + '_' + usage + ']', f).val();
        params.type_sf = jQuery('input:radio[name=type_' + usage + ']:checked', f).val();
        params.typeInfo_sf = jQuery('#typeInfo_' + usage, f).val();
        params[i_type + 'State_sf'] = jQuery('[name=' + i_type + 'State_' + usage + ']', f).val();
        params[other_field + 'State_sf'] = jQuery('[name=' + other_field + 'State_' + usage + ']', f).val();
        params.itdLPxx_input = i_type;
        params.itdLPxx_odv_type = params.type_sf;

    }

    params.itdLPxx_usage = usage;
    params.itdLPxx_checkText = value;

    this.checkText = value;

    if (loc_server_active !== '1') {
        // Zweifeld
        jQuery.get(this.config.url.replace('XSLT', 'XML'), params, this.on_success, 'xml');
    } else {
        // Einfeld
        jQuery.getJSON(this.config.url, params, this.on_success);
    }
};


mdvSug.create_img_str = function(t) {
    
    return this.imgTag.replace(/#IMG#/, function (m) {

                if (t === 'stop') {
                    return 'stop.gif';
                }

                if (t === 'poi') {
                    return 'pin.png';
                }

                return 'address.gif';

            });
        
};



mdvSug.on_success = function (efa) {

    var i, len, point, type, txt, add, r, usage, i_type, odv_type, elem_name, state, results = '';

    var _inject = function (html_str) {

        var odvSuggest, odvSuggestDiv, elem, input_pos;

        odvSuggest = document.createElement('div');
        odvSuggest.id = 'odvSg';
        odvSuggest.innerHTML = html_str;

        odvSuggestDiv = document.createElement('div');
        odvSuggestDiv.className = 'odvSg';
        odvSuggestDiv.id = 'odvOverlay';
        odvSuggestDiv.style.display = 'none';
        
        // keep a jq ref
        elem = jQuery(odvSuggestDiv);
        
        // append to body
        jQuery('body').append(elem.append(odvSuggest));
        
        // get absolute position of triggering input box 
        input_pos = jQuery(mdvSug.currentElem).offset();
        
        // move and display it 
        elem.css({
            'top': (input_pos.top + 18) + 'px',
            'left': (input_pos.left + 40) + 'px',
            'display': 'block'
        });
    };

    // always remove overlay if present
    jQuery('#odvOverlay').remove();


    // handle XML (Zweifeldeingabe)
    if (efa.xml !== undefined || efa.characterSet !== undefined) {

        usage = jQuery('itdLayoutParam[name=usage]', efa).attr('value');
        i_type = jQuery('itdLayoutParam[name=input]', efa).attr('value');
        odv_type = jQuery('itdLayoutParam[name=odv_type]', efa).attr('value');

        elem_name = 'odvPlaceElem';

        if (i_type === 'name') {
            elem_name = 'odvNameElem';
            state = jQuery('itdOdvName', efa).attr('state');
            if (state === 'notidentified') {
                return false;
            };
        } else {
            state = jQuery('itdOdvPlace', efa).attr('state');
            if (state === 'notidentified') {
                return false;
            };
        }

        jQuery(efa).find(elem_name).each(function (idx) {

            if (i_type === 'name') {
                add = mdvSug.create_img_str(odv_type);
                txt = add + jQuery(this).text();
            } else {
                txt = jQuery(this).text();
            }

            r = mdvSug.opt;
            r[1] = idx;
            r[3] = jQuery(this).attr('stateless');
            r[5] = jQuery(this).text();
            r[7] = usage;
            r[9] = txt;
            results += r.join('');
        });

        _inject(results);

        return true;
    }


    // handle JSON (Einfeld)
    if (!efa.stopFinder) {
        return false;
    }

    usage = efa.parameters[1].value;

    // full hit or list?
    len = (efa.stopFinder.point) ? 1 : efa.stopFinder.length;

    // sort result list if more than one hit 
    if (len > 1) {
        efa.stopFinder.sort(mdvSug.compare_types);
    } else {
        // no hit
        return;
    }

    for (i = 0; i < len; i += 1) {

        point = efa.stopFinder[i] || efa.stopFinder.point;

        txt = point.name;

        type = point.anyType.toLowerCase();

        if (type === 'loc') {
            txt = point.ref.place;
        }
        
        add = mdvSug.create_img_str(type);

        r = mdvSug.opt;
        r[1] = i;
        r[3] = point.stateless;
        r[5] = txt;
        r[7] = usage;
        r[9] = add + txt;
        results += r.join('');
    }

    _inject(results);

};

mdvSug.submit_entry = function (value, txt, usage) {
    var i_type = this.currentInput;

    //console.log(value + ', usage: ' + usage + ', i_type: ' + i_type + ', txt: ' + txt);
    
    // submit form immediately
    if (this.config.submit === true) {
        if (jQuery('#' + i_type + 'State_' + usage).val() === "empty") {
            jQuery('#' + i_type + '_' + usage).val(value);
        } else {
            jQuery('#' + i_type + 'Info_' + usage).val(value);
        }
        jQuery('form')[0].submit();
        
    // only populate input field and nameInfo/placeInfo
    } else {
         jQuery('#' + i_type + 'Info_' + usage).val(value);       
         jQuery('#' + i_type + '_' + usage).val(txt);   
         jQuery('#odvOverlay').remove();
         setFocus (); 
    }    
};

mdvSug.compare_types = function (a, b) {

    if (a.type === 'loc') {
        a.sortPos = 1;
    } else if (a.type === 'stop') {
        a.sortPos = 2;
    } else if (a.type === 'poi') {
        a.sortPos = 3;
    } else {
        a.sortPos = 4;
    }

    if (b.type === 'loc') {
        b.sortPos = 1;
    } else if (b.type === 'stop') {
        b.sortPos = 2;
    } else if (b.type === 'poi') {
        b.sortPos = 3;
    } else {
        b.sortPos = 4;
    }

    return a.sortPos > b.sortPos;
};


// add event handler
jQuery(document).ready(function () {

    jQuery(document).keyup(function (event) {

        var el, parentSg = jQuery('#odvSg')[0];
        
        if (jQuery('#sug_0')[0] && (event.keyCode === 40 || event.keyCode === 38)) {

            var counter = parentSg.childNodes.length;

            // ARROW DOWN
            if (event.keyCode === 40) {
                if (sugFocusId < counter - 1) {
                    sugFocusId++;
                }
            }
            // ARROW UP
            else if (event.keyCode === 38 && sugFocusId > 0) {
                sugFocusId--;
            }
            jQuery('div.actSug').removeClass('actSug');
            el = jQuery('#sug_' + sugFocusId)[0];
            if (el) { 
                el.className = 'actSug';
                el.firstChild.focus();
            }
        }
        // ESC        
        if (jQuery('#sug_0')[0] && event.keyCode === 27) {
            jQuery('#odvOverlay').hide();
        }

    });

});
