// ----------------------------------------------------------------------------

// Zoom Search Engine 2.0 (25/8/2003)

//

// This file (search.js) is the JavaScript search front-end for client side 

// searches using index files created by the Zoom Search Engine Indexer.

//

// email: zoom@wrensoft.com

// www: http://www.wrensoft.com

//

// Copyright (C) Wrensoft 2000-2003

//

// This script performs client-side searching with the index data file

// (zoom_index.js) generated by the Zoom Search Engine Indexer. It allows you

// to run searches on mediums such as CD-ROMs, or other local data, where a

// web server is not available.

//

// We recommend against using client-side searches for online websites because

// it requires the entire index data file to be downloaded onto the user's 

// local machine. This can be very slow for large websites, and our server-side

// search scripts (search.php and search.asp) are far better suited for this.

// However, JavaScript is still an option for smaller websites in a limited

// hosting situation (eg: no php or asp)

// ----------------------------------------------------------------------------



// ----------------------------------------------------------------------------

// Settings (change if necessary)

// ----------------------------------------------------------------------------



// Highlight matched words in results

var Highlighting = 0;              // 0 = off, 1 = on

var HighlightColor = "#FFFF40";    // Highlight colour



// The options available in the dropdown menu for number of results

// per page

var PerPageOptions = new Array(10, 20, 50, 100);



var FormFormat = 0;    //0 = No search form (note that you must pass parameters to 

                       //    the script directly from elsewhere on your website).

                       //1 = Basic search form

                       //2 = Advanced search form (with options)



                                   

var OutputStyle = 1;    //0 = Basic Style, Page Title, Score and URL

                        //1 = Descriptive Style, Match number, Page Title,

                        //    Page description, Score and URL                



var ZoomInfo = 1;       //0 = Don't display Zoom info line at bottom of search

                        //1 = Display Zoom info line at bottom of search

 

var WordSplit = 1;      //0 = Only split input search phrase into words when a

                        //    Space character is found

                        //1 = Split input search phrase at Space ' ',

                        //    UnderScore '_' , Dash '-' and Plus '+' characters



// ----------------------------------------------------------------------------

// Helper Functions

// ----------------------------------------------------------------------------

             

// This function will return the value of a GET parameter 

function getParam(paramName) 

{

    paramStr = document.location.search;

    if (paramStr == "") 

        return ""; 

    // remove '?' in front of paramStr

    if (paramStr.charAt(0) == "?")

        paramStr = paramStr.substring(1, paramStr.length);

                

    arg = (paramStr.split("&"));

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

        arg_values = arg[i].split("=")

        if (unescape(arg_values[0]) == paramName) {

            return unescape(arg_values[1]);

        }

    }   

    return;

}



// Compares the two values, used for sorting output results

// Results that match all search terms are put first, highest score

function SortCompare (a, b) 

{

    if (a[2] < b[2]) return 1;

    else if (a[2] > b[2]) return -1;

    else if (a[1] < b[1]) return 1;

    else if (a[1] > b[1]) return -1;

    else return 0;    

} 



function pattern2regexp(pattern) {

    pattern = pattern.replace(/\*/g, ".*");

    pattern = pattern.replace(/\?/g, ".?"); 

    return "^" + pattern + "$";

}

        

function HighlightDescription(line) {       

    res = line;            

    for (i = 0; i < matchwords_num; i++) {

        // replace with marker text, assumes [;:] and [:;] is not the search text...                        

        res = res.replace(new RegExp("\\b("+matchwords[i]+")\\b", "gi"), "[;:]$1[:;]");             

    }    

    // replace the marker text with the html text

    // this is to avoid finding previous <span>'ed text.    

    res = res.replace(/\[;:\]/g, "<span style=\"background: " + HighlightColor + "\">");

    res = res.replace(/\[:;\]/g, "</span>");

    return res;

}



// ----------------------------------------------------------------------------

// Parameters initialisation (globals)

// ----------------------------------------------------------------------------



var query = getParam("zoom_query");

query = query.replace(/\+/g, " ");  // replace the '+' with spaces 



var per_page = parseInt(getParam("zoom_per_page"));

if (isNaN(per_page)) per_page = 10;



var page = parseInt(getParam("zoom_page"));

if (isNaN(page)) page = 1;

    

var andq = parseInt(getParam("zoom_and"));

if (isNaN(andq)) andq = 0;



var searchWords = new Array();

var data = new Array();

var output = new Array();



if (Highlighting == 1) {

    var matchwords = new Array();

    var matchwords_num = 0;

}





// ----------------------------------------------------------------------------

// Main search function starts here

// ----------------------------------------------------------------------------



function ZoomSearch() {

    

    // Display the form

    if (FormFormat > 0) {

        document.writeln("<form method=\"GET\" action=\"" + document.location.pathname + "\">");

        document.writeln("<input type=\"text\" name=\"zoom_query\" size=\"20\" value=\"" + query + "\">");

        document.writeln("<input type=\"submit\" value=\"Search\">");

        if (FormFormat == 2) {

            document.writeln("<small>Results per page:");

            document.writeln("<select name='zoom_per_page'>");

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

                document.write("<option");

                if (PerPageOptions[i] == per_page)

                    document.write(" selected=\"selected\"");

                document.writeln(">" + PerPageOptions[i] + "</option>");

            }                               

            document.writeln("</select></small></p>");

            document.writeln("<small>Match: ");

            if (andq == 0) {

                document.writeln("<input type=\"radio\" name=\"zoom_and\" value=\"0\" checked>any search words");

                document.writeln("<input type=\"radio\" name=\"zoom_and\" value=\"1\">all search words");

            } else {

                document.writeln("<input type=\"radio\" name=\"zoom_and\" value=\"0\">any search words");

                document.writeln("<input type=\"radio\" name=\"zoom_and\" value=\"1\" checked>all search words");

            }

            document.writeln("</small>");

        }

        document.writeln("</form>");

    }



    // give up early if no search words provided

    if (query.length == 0) {

        //document.writeln("No search query entered.<br>");

        if (ZoomInfo == 1)

            document.writeln();

        return;

    }

            

    if (WordSplit == 1) 

        query = query.replace(/[+-_]/g, " "); // replace '+', '-', '_' with spaces.

    

    // split search phrase into words   

    searchWords = query.split(" "); // split by spaces.

    

    document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=4 color=#666666>Search Results for \"" + query + "\"</font><p>");

    

    numwords = searchWords.length;  

    kw_ptr = 0;

    outputline = 0;

    usewildcards = 0;

    ipage = 0;

    

    for (sw = 0; sw < numwords; sw++) {     

        

        re = new RegExp(pattern2regexp(searchWords[sw]), "gi");

                

        for (kw_ptr = 0; kw_ptr < keywords.length; kw_ptr++) {

            data = keywords[kw_ptr].split(","); 

            

            //match_result = searchWords[sw] == data[0];        

            match_result = data[0].search(re);          

                        

            if (match_result != -1) {                               

                // keyword found, include it in the output list             

                

                if (Highlighting == 1) {

                    // Add to matched words list                                        

                    // Check if its already in the list

                    for (i = 0; i < matchwords.length && matchwords[i] != data[0]; i++);                                

                    if (i == matchwords.length) // not in list

                        matchwords_num = matchwords.push(data[0]);                                                          

                }

                

                for (kw = 1; kw < data.length; kw += 2) {

                    // check if page is already in output list

                    pageexists = 0;                 

                    ipage = data[kw];                                                                       

                    for (ol = 0; ol < outputline; ol++) {                       

                        

                        if (output[ol][0] == ipage) {

                            // page is already in output list so add to count and extra

                            if (output[ol][1] > 10000) {

                                // take it easy if its too big (to prevent huge scores)

                                output[ol][1] += 1;

                            } else {

                                output[ol][1] += parseInt(data[kw+1]);  // add in score

                                output[ol][1] *= 2;             // double score as we have two words matching

                            }

                            output[ol][2] += 1;                 // increase word match count

                            pageexists = 1;

                        }                       

                    }

                    if (pageexists == 0) {

                        // new page to add to list                      

                        // create 3 fields for each output

                        output[outputline] = new Array(0,0,0);                  

                        // now fill in the values for each field

                        output[outputline][0] = ipage;      // page index

                        output[outputline][1] = parseInt(data[kw+1]);   // score

                        output[outputline][2] = 1;          // single word match only

                        outputline++;               

                    }

                                        

                }

                // if (useWildCards == 0) 

                //break;    // this search word was found, so skip to next

            }

            // return to start of keywords list...      

        }   

    }

    

    // Get number of pages matched

    matches = outputline;

    

    // Sort results in order of score, use "SortCompare" function

    if (matches > 1)

        output.sort(SortCompare);



    // Count number of output lines that match ALL search terms

    oline = 0;

    fullmatches = 0;

    

    if (numwords > 1) {     

        while ((oline < matches)) {

            if (output[oline][2] == numwords) {

                fullmatches++;

            }       

            oline++;

        }       

        if (andq == 1)

            matches = fullmatches;

    }

    

    //Display search result information

    document.writeln("<small>");

    if (matches == 1)

        document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#666666><b>1</b> result found.</font><br>");

    else if (matches == 0)

        document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#666666>No results found.</font><br>");

    else if (numwords > 1 && andq == 0) {

        //OR

        SomeTermMatches = matches - fullmatches;

        document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#666666><b>" + fullmatches + "</b> pages found containing all search terms.</font><br>");

        if (SomeTermMatches > 0)

            document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#666666><b>" + SomeTermMatches + "</b> pages found containing some search terms.</font>");

        document.writeln("</font)<br>");

    }

    else if (numwords > 1 && andq == 1) //AND

        document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#666666><b>" + fullmatches + "</b> pages found containing all search terms.</font><br>");

    else

        document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#666666><b>" + matches + "</b> results found.</font><br>");

    

    document.writeln("</small>\n");

    

    // number of pages of results

    num_pages = Math.ceil(matches / per_page);

    if (num_pages > 1)

        document.writeln("<br><font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#333399><b>" + num_pages + " pages of results.</b></font><br>\n");

        

    // determine current line of result from the output array

    if (page == 1) {

        arrayline = 0;

        out_counter = 0;

        outStartsAt = 0;

    } else {

        //arrayline = ((page - 1) * per_page);

        arrayline = 0;

        out_counter = 0;

        outStartsAt = ((page - 1) * per_page);

    }

    

    // the last result to show on this page

    result_limit = outStartsAt + per_page;  

    

    // display the results

    while (arrayline < matches && arrayline < result_limit) {

                

        if ((andq == 1) && (numwords > 1) && (output[arrayline][2] < numwords)) {

            arrayline++;

            continue;               

        }

        

        out_counter++;      

        if (out_counter <= outStartsAt)

        {

            arrayline++;

            continue;

        }

        

        ipage = output[arrayline][0];       

        score = output[arrayline][1];       

        if (OutputStyle == 0) {

            // basic style

            document.writeln("<p>Page: <a href=\"" + urls[ipage] + "\">" + titles[ipage] + "</a><br>\n");

            document.writeln("Score: " + score + "&nbsp;&nbsp;<small><i>URL:" + urls[ipage] + "</i></small></p>\n");            

        } else {            

            // descriptive style

            document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#333399><p><b>" + (out_counter) + ".&nbsp;<a href=\"" + urls[ipage] + "\"><font color=#333399>" + titles[ipage] + "</a></b></font><br>");

            if (Highlighting == 1)

                document.writeln(HighlightDescription(descriptions[ipage]));

            else

                document.writeln("<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#666666>" + descriptions[ipage] + "</font>");      

            document.writeln("...<br>\n");

            document.writeln("<font color=\"#999999\"><small><i>Terms matched: " + output[arrayline][2] + " Frequency: " + score + "&nbsp;&nbsp;URL: " + urls[ipage] + "</i></small></font></p>\n<font face=Verdana, Arial, Helvetica, sans-serif size=1 color=#666666>");

        }       

        arrayline++;

    }

    

    // Show links to other result pages

    if (num_pages > 1) {

        document.writeln("<font size=1 face=Verdana, Arial, Helvetica, sans-serif color=#666666><b><p>Result Pages: </b></font>");

        if (page > 1)

            document.writeln("<a href=\"" + document.location.pathname + "?zoom_query=" + query + "&zoom_page=" + (page-1) + "&zoom_per_page=" + per_page + "&zoom_and=" + andq + "\"><font size=1 face=Verdana, Arial, Helvetica, sans-serif color=#666666>&lt;&lt; Previous</a></font>&nbsp;");

        

        for (i = 1; i <= num_pages; i++) {

            if (i == page) {

                document.writeln("<font size=1 face=Verdana, Arial, Helvetica, sans-serif color=#333399><b>"+page + "</b></font>");          

            } else {

                document.writeln("<a href=\"" + document.location.pathname + "?zoom_query=" + query + "&zoom_page=" + i + "&zoom_per_page=" + per_page + "&zoom_and=" + andq + "\"><font size=1 face=Verdana, Arial, Helvetica, sans-serif color=#666666>" + i + "</a></font>&nbsp;");

            }

        }



        if (page != num_pages)

            document.writeln("<a href=\"" + document.location.pathname + "?zoom_query=" + query + "&zoom_page=" + (page+1) + "&zoom_per_page=" + per_page + "&zoom_and=" + andq + "\"><font size=1 face=Verdana, Arial, Helvetica, sans-serif color=#666666>Next &gt;&gt;</a></font>&nbsp;");            

    }



    document.writeln("<br><br>");

    

    if (ZoomInfo == 1)

        document.writeln();

    

}

