/**
 * The next search result position.
 *
 * @var     int
 * @access  private
 */
var search_reload_flow_count = 0;

/**
 * Number of already loaded records.
 *
 * @var     int
 * @access  private
 */
var curr_num_search_records = 0;

/**
 * Current search status (new search
 * or just more results to get).
 *
 * @var     boolean
 * @access  private
 */
var new_search = true;

/**
 * RPC source.
 *
 * @var     string
 * @access  private
 */
var url = '/rpc.php';

/**
 * Last query string.
 *
 * @var     string
 * @access  private
 */
var search_query = false;

/**
 * Number of search results.
 *
 * @var     int
 * @access  private
 */
var search_results_count = 0;

/**
 * Page load cache.
 *
 * @var     int
 * @access  private
 */
var load_cache = new Array();


/**
 * Activates search action and calls ajax request function on submit.
 *
 * @return  void
 *
 * @access  public
 */
function activateSearch()
{
    if ( $('ajaxform') ) {
        $('ajaxform').onsubmit = function() { return startNewSearch(); };

        if ( $('search_string') ){
            $('search_string').focus();
        }
    }

    if ( a = parseLocationBar() ) {
        //if ( a['start'] ){
        //    search_reload_flow_count = a['start'];
        //}

        $('search_string').value = decodeURI(a['search_string']);
        displayPage();
        doSearch();
    }
}


/**
 * Activates spelling suggestion.
 *
 * @return  void
 *
 * @access  public
 */
function activateSpellingSuggestions()
{
    if ( $('search_auto_complete') ){
        var id_input_text      = 'search_string';
        var id_div_suggestion  = 'search_auto_complete';
        var ajax_url           = url + '?function=spelling&langcode=' + langcode;

        var sug = new Ajax.Autocompleter( id_input_text, id_div_suggestion, ajax_url,
            {paramName: "search_string", frequency: 0.2, minChars: 4, tokens: ' '}
        );
    }
}


/**
 * Starts a new search.
 *
 * @return  void
 *
 * @access  public
 */
function startNewSearch()
{
    if ( $F('search_string') ){
        new_search               = true;
        search_reload_flow_count = 0;
        curr_num_search_records  = 0;
        load_cache               = new Array();

        displayPage();
        doSearch();
    }

    return false;
}


/**
 * Removes items from startpage and displays result page.
 *
 * @return  void
 *
 * @access  public
 */
function displayPage()
{
    if( $('content_elements') && new_search == true ){
        $('content_elements').parentNode.removeChild($('content_elements'));
    }

    $('page_content').style.visibility = 'visible';
    setContentAreaHeight();
}


/**
 * Removes all content blocks from the navigation section.
 *
 * If you do create a new content block than you do need
 * to add the one in here.
 *
 * @return  void
 *
 * @access  public
 */
function showSearchTerm()
{
    if($('content_nav_details')) {
        $('content_nav_details').parentNode.removeChild($('content_nav_details'));
    }

    if($('content_prev_box')) {
        $('content_prev_box').parentNode.removeChild($('content_prev_box'));
    }

    if($('content_prev_box_download')) {
        $('content_prev_box_download').parentNode.removeChild($('content_prev_box_download'));
    }

    if (search_query.length > 25) {
        $('content_title').innerHTML = '<h1>' + search_query.substr(0, 25) + '...</h1>';
    }
    else {
        $('content_title').innerHTML = '<h1>' + search_query + '</h1>';
    }
}



/**
 * Function shows search filter block.
 *
 * The search filter input fields will be displayed
 * and set up here. If you do need a new filter
 * option you need to add it here.
 *
 * @return  void
 *
 * @access  public
 */
function showSearchFilter()
{
    if ( !$('content_search_filter') ){
        var cfil = $('content_nav_box');
        var parent = appendNode( cfil, 'div', 'content_search_filter', false );
        var child  = appendNode( parent, 'h2', false, language['search_filter'] );

        var fld  = '<select name="search_year" id="search_year"><option value="">&nbsp;</option><option value="2008">2008</option><option value="2007">2007</option><option value="2006">2006</option><option value="2005">2005</option><option value="2004">2004</option><option value="2003">2003</option><option value="2002">2002</option><option value="2001">2001</option><option value="2000">2000</option></select>';
        var child  = appendNode( parent, 'p', false, language['search_year'] );
        Element.addClassName( child, 'name' );
        var child  = appendNode( parent, 'p', false, fld );
        Element.addClassName( child, 'value' );
        $('search_year').onchange = function() { return startNewSearch(); }

        var fld  = '<select name="search_lang" id="search_lang"><option value="">&nbsp;</option><option value="en">english</option><option value="de">deutsch</option></select>';
        var child  = appendNode( parent, 'p', false, language['search_lang'] );
        Element.addClassName( child, 'name' );
        var child  = appendNode( parent, 'p', false, fld );
        Element.addClassName( child, 'value' );
        $('search_lang').onchange = function() { return startNewSearch(); }

        var fld  = '<select name="search_sort" id="search_sort"><option value="0">' + language['search_relevance'] +
            '</option><option value="1">' + language['search_year'] + '</option></select>';

        var child  = appendNode( parent, 'p', false, language['search_mode'] );
        Element.addClassName( child, 'name' );
        var child  = appendNode( parent, 'p', false, fld );
        Element.addClassName( child, 'value' );
        $('search_sort').onchange = function() { return startNewSearch(); }
    }
}



/**
 * Performs ajax search request.
 *
 * @return  void
 *
 * @access  public
 */
function doSearch ()
{
    if ( !load_cache[search_reload_flow_count] ){
    	var f = $('ajaxform');
    	search_query = $F('search_string'); // serialize all data from the form
        load_cache[search_reload_flow_count] = true;

	    showLoadingStatus();
	    showSearchTerm();
        showResultsCount();
	    showSearchFilter();

    	if ( new_search == true ){
    	   f.disabled = true;
    	}

    	var params = Form.serialize(f);
        var a = { 'function': 'search' , 'start': search_reload_flow_count };
        if ( $F('search_sort') ){ a['sortmode'] = $F('search_sort'); }
        if ( $F('search_lang') ){ a['filter_lang'] = $F('search_lang'); }
        if ( $F('search_year') ){ a['filter_year'] = $F('search_year'); }
        var h = $H(a);
    	var params = params + '&' + h.toQueryString();

    	// get response
    	var myAjax = new Ajax.Request( url, {
    	    method: 'get',
    	    parameters: params,
    	    onComplete: showSearchResponse,
    	    onFailure: function(req) {alert(req.responseText)},
    	    onException: function(t,e) {alert(e);}
	    });

    	// update global location bar
    	setSearchLocation();
    }
}



/**
 * Show error message.
 *
 * @return  void
 *
 * @access  public
 */
function showError( response, test )
{
    alert( 'Critical Ajax Error: ' + test );
    return false;
}


/**
 * Shows Onload Status.
 *
 * @return  void
 *
 * @access  public
 */

function showLoadingStatus()
{
    Element.addClassName($('content_nav_box'), 'loadingani');
    reloadAdbox();
    return true;
}



/**
 * Hides OnLoad Status.
 *
 * @return  void
 *
 * @access  public
 */

function hideLoadingStatus()
{
    Element.removeClassName($('content_nav_box'), 'loadingani');

    return true;
}



/**
 * Shows and adds search results.
 *
 * @return  void
 *
 * @access  public
 */
function showSearchResponse( originalRequest, json )
{
    var b = $('ajaxform');
    var s = $('content_main_box');
	var h = $('content_header');
	var search_query = $('search_string').value;
	var domain = getDomainName();

	String.prototype.urlEncode = function(){ return encodeURIComponent(this); }

	if ( new_search == true ){
        b.disabled = false;
	}

    hideLoadingStatus();

    if ( !$('content_elements') ) {
        var records = document.createElement('div');

        s.appendChild(records);
        records.id = 'content_elements';
    }

    var supernode = $('content_elements');

    // if there is no result
    if ( (!json || json.matches.length == 0) && new_search == true ) {
        var parent = appendNode( supernode, 'div');
        Element.addClassName(parent, 'content_element');
        var child = appendNode( parent, 'p', false, language['no_results']);
        Element.addClassName(child, 'title');

        enableSlider();
        s.scrollTop = 0;
        disableSlider();

        search_results_count = 0;
    }
    else {

		search_query = urlEncode(search_query);

        // show results
        for (i=0; i<json.matches.length; i++) {
            if ( json.matches[i].title.length > 1 && !$(json.matches[i].id.toString()) ){
                var parent = appendNode( supernode, 'div', json.matches[i].id.toString() );
                Element.addClassName(parent, 'content_element');

                var child = appendNode( parent, 'p' );
                Element.addClassName(child, 'title');

                position = $$('.content_element').length;

                var a  = appendNode( child, 'a');
                a.innerHTML = json.matches[i].title;
                a.href = domain + '/redirect/' + json.matches[i].id + '/' + position + '/' + search_query;

                if ( json.matches[i].creator.length > 2 ){
                    var creators = json.matches[i].creator;
                }
                else {
                    var creators = language['no_author'] + '...';
                }

                var child = appendNode( parent, 'p', false, creators);
                Element.addClassName(child, 'creator');


                if ( json.matches[i].description.length > 2 ){
                    var child = appendNode( parent, 'p' );
                    Element.addClassName(child, 'description');
                    child.innerHTML = json.matches[i].description;
                }

                var child = appendNode( parent, 'div' );
                Element.addClassName(child, 'rank');
                child.innerHTML = json.matches[i].pagerank;

                curr_num_search_records++;

                Event.observe(parent, 'mouseover', startPreviewTask);
                Event.observe(parent, 'mouseout', clearMouseOverIndex);
            }
        }

        //reset scrollbar to zero (top) position
        if ( new_search == true ){
            s.scrollTop = 0;
            initSlider(); // enable slider
        }

        search_results_count = json.total_found;
    }

	if ( search_reload_flow_count == 0 ){ observeSearchElementsPosition(); }
    if ( !json || !json.end_index ){ search_reload_flow_count = 0; }
    else { search_reload_flow_count = json.end_index; }

	setSliderPositionByContentPosition();
}



/**
 * Update location bar with last query parameters.
 *
 * @return  void
 *
 * @access  public
 */
function setSearchLocation()
{
    if ( search_query ){
        var query = $H({ 'search_string': search_query }).toQueryString()
        window.location.hash = query;
    }
}


function urlEncode(str)
{
	str = str.toString();
	str = encodeURIComponent(str);
    return str.replace(/%20/g, '+');
}

/**
 * Parses location bar.
 *
 * Function parses location bar (local anchor) and gives back an
 * array of parameters.
 *
 * @return  array or false
 *
 * @access  public
 */
function parseLocationBar()
{
    var q = window.location.hash;
    q = q.replace('#','');

    var a = new Array();

    for( var i=0; i < q.split('&').length; i++ ) {
        var h = q.split('&')[i];
        var params = h.split('=');
        a[params[0]] = params[1];
    }

    if ( a['search_string'] ){
        return a;
    }

    return false;
}



/**
 * Loads new search results and updates search
 * scroll count index.
 *
 * @return  void
 *
 * @access  public
 */
function loadNewSearchResults()
{
    if ( search_query && $('content_elements') ){
        var box = $('content_main_box');
        var chl = $('content_elements');

        var h = Element.getHeight(box);
        var s = box.scrollTop;

        var children = chl.childNodes;

        var startpos = 0;
        var endpos = 0;

        if ( h < box.scrollHeight ){
            while( (s + h - 100) >= children[endpos].offsetTop ) {endpos++; }

            endpos++;

            if ( (endpos + 10) >= curr_num_search_records ){
                new_search = false;
                doSearch();
            }
        }
        else {
            endpos = search_results_count;
        }

        if ( !children || !children[startpos] || !children[startpos+1] ){
            startpos = 1;
        } else {
            while( s >= children[startpos].offsetTop ) { startpos++; }
        }


        showResultsCount(startpos, endpos, search_results_count);
    }
}


/**
 * Show the results block list.
 *
 * The function gets called to display to amount
 * of search hits.
 *
 * @return  void
 *
 * @access  public
 */
function showResultsCount( start, end, offset )
{
    if ( !$('content_search_details') ){
        var cnav = $('content_nav_box');
        var parent = appendNode( cnav, 'div', 'content_search_details', false );
    }
    else {
        var parent = $('content_search_details');
        parent.innerHTML = '';
    }

    if ( start && end && offset ){
        var str  = start + ' - ' + end + ' ' + language['of'] + ' ' + offset;
    }
    else {
        var str = '&nbsp;';
    }

    var child  = appendNode( parent, 'p', false, language['search_hits'] );
    Element.addClassName( child, 'name' );
    var child  = appendNode( parent, 'p', false, str );
    Element.addClassName( child, 'value' );
}



/**
 * Appends a dom child node to a parent node.
 *
 * @return  object
 *
 * @access  public
 */
function appendNode( parent, type, id, innerHTML )
{
    var child = document.createElement(type);

    if ( id ){ child.id = id; }
    if ( innerHTML ) { child.innerHTML = innerHTML }

    parent.appendChild(child);

    return child;
}


//
// Start core event observer handler
//
Event.observe(window, 'load', activateSearch);
//Event.observe(window, 'load', activateSpellingSuggestions);

