﻿/*
jQuery Google Search Plugin 0.1
Copyright © 2010 Tom Verlihay//////////

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
/////////////////////////////////////////////////////////////////////
*/

(function ($) {
    //GLOBAL VARIABLES

    var opts;

    $.gSearchDefaults = {
        webSearch: true,
        videoSearch: false, //not used
        blogSearch: false, //not used
        newsSearch: false, //not used
        imageSearch: false, //not used
        bookSearch: false, //not used
        patentSearch: false, //not used
        localSearch: false, //not used
        lsCenter: '', //this is the center for the local search if needed to be static
        customSearchBox: true,
        searchContainer: '#gSearch',  //for the actual textbox. if customSearchBox is used this won't be needed //src: searchControl.draw(divID)
        resultsDIV: 'gResults', //if the search is to be displayed in page, display it here. DO NOT USE '#'
        expandMode: 'EXPAND_MODE_OPEN',
        resultsPerPage: 8, //Max of 8
        siteRestriction: '', //like amazon.com
        searchBoxID: '#txtSearch', //used for a custom search, the value gets placed in the searchControl.execute(txtVal) command on submit
        submitBtn: '#btnSearch', //the button used to submit the search.  Can be just a link or a button
        useCB: false, //use colorbox?  must have jquery.colorbox.js
        CBTitle: '', //if using colorbox, this will add a title to the top of the colorbox
        onComplete: function () { },
        callback: function () { }
    };

    function gSearchObject(elementId, options) {
        /* Public properties */
        this.ElementId = elementId;
        opts = $.extend($.gSearchDefaults, options);
        $(opts.submitBtn).click(function () {
            prepareSearch($(opts.searchBoxID).val());
            return false;
        });
    }

    function prepareSearch(searchTerm) {
        $('head').prepend('<script type="text/javascript" language="javascript">var rCount;var firstRun = false; /*Added dynamically by gSearch to create a global variable for the search results count*/</script>');
        $('head').prepend('<script type="text/javascript" language="javascript">var searched = false; /*Added dynamically by gSearch to create a global variable for the search results count*/</script>');

        if (opts.useCB) {
            if ($.fn.colorbox != null || $.colorbox != null) { //added an option to remove the '.fn' from colorbox to make it compliant with the latest release
                $('head').prepend('<script type="text/javascript" language="javascript">var wSearch; /*Added dynamically by gSearch to create a global variable for the search*/</script>');
                var cbDiv = '<div style="display:none;"><div id="gSearchBox" style="display:none;"></div><div id="' + opts.resultsDIV + '"></div></div>';
                $('body').append(cbDiv);
            }
        }

        //var searchControl = new google.search.SearchControl(); //init the search control
        var sOptions = new google.search.SearcherOptions(); //set variable to receive the search options
        var dOptions = new google.search.DrawOptions(); //set the variable to receive the draw options

        if (opts.webSearch) {
            wSearch = new google.search.WebSearch();  //create a new search object

            if (opts.siteRestriction.length > 0) {
                wSearch.setSiteRestriction(opts.siteRestriction); //limits the search to a particular site
            }
            //searchControl.addSearcher(wSearch, sOptions);
        }

        //        if (opts.videoSearch) { searchControl.addSearcher(new google.search.VideoSearch()); }
        //        if (opts.blogSearch) { searchControl.addSearcher(new google.search.BlogSearch()); }
        //        if (opts.newsSearch) { searchControl.addSearcher(new google.search.NewsSearch()); }
        //        if (opts.imageSearch) { searchControl.addSearcher(new google.search.ImageSearch()); }
        //        if (opts.bookSearch) { searchControl.addSearcher(new google.search.BookSearch()); }
        //        if (opts.patentSearch) { searchControl.addSearcher(new google.search.PatentSearch()); }
        //        if (opts.localSearch) { searchControl.addSearcher(new google.search.LocalSearch()); }

        if (opts.customSearchBox) {
            wSearch.setResultSetSize(opts.resultsPerPage);
            wSearch.setSearchCompleteCallback(this, displayResults);
        } else {
            //searchControl.draw(document.getElementById(opts.resultsDIV), dOptions); //this is where the textbox will render
        }
        wSearch.execute(searchTerm);
    }

    function displayResults() {
        if (!searched && wSearch.cursor != null) {
            searched = true;
            firstRun = false;
            wSearch.gotoPage(wSearch.cursor.pages.length - 1);
        }

        if (rCount == null && wSearch.cursor != null) {
            rCount = wSearch.cursor.estimatedResultCount;
        }

        if (wSearch.results && wSearch.results.length > 0) {
            var results = wSearch.results;
            var tmpString = "";
            if (opts.useCB) {
                $('#' + opts.resultsDIV).html('<h1>' + opts.CBTitle + '</h1>');
            }
            for (var i = 0; i < results.length; i++) {
                var result = results[i];
                tmpString = tmpString + '<div class="rBox">';
                tmpString = tmpString + '<div class="rTitle"><a href="' + result.url + '">' + result.titleNoFormatting + '</a></div>';
                tmpString = tmpString + '<div class="rDescr">' + result.content + '</div>';
                tmpString = tmpString + '</div>';
            }
            $('#' + opts.resultsDIV).append(tmpString);
            tmpString = "";

            addPaginationLinks(wSearch);
            loadCB();
        } else {
            $('#' + opts.resultsDIV).append('No Results Found.');
            loadCB();
        }
    }

    function addPaginationLinks() {
        // The cursor object has all things to do with pagination
        if (wSearch.cursor != null) {
            var cursor = wSearch.cursor;
            var curPage = cursor.currentPageIndex; // check what page the app is on

            $('#' + opts.resultsDIV).append('<div id="paging"></div>');
            //console.log(parseInt(rCount / opts.resultsPerPage));
            var pageCount;
            if (rCount % opts.resultsPerPage > 0) {
                pageCount = parseInt(rCount / opts.resultsPerPage) + 1;
            } else {
                pageCount = parseInt(rCount / opts.resultsPerPage);
            }
            for (var i = 0; i < pageCount; i++) {
                var page = cursor.pages[i];
                if (curPage == i) { // if we are on the curPage, then don't make a link
                    $('#paging').append('&nbsp;' + page.label + '&nbsp;');
                } else {
                    // If we aren't on the current page, then we want a link to this page.
                    // So we create a link that calls the gotoPage() method on the searcher.
                    var tmpLabel = String(page.label);
                    var tmpString = '&nbsp;<a href="javascript:void(0)" id="pageNumber' + tmpLabel + '" onclick="wSearch.gotoPage(' + i + ');">' + tmpLabel + '</a>&nbsp;';
                    $('#paging').append(tmpString);
                }
            }
            if (!firstRun) {
                firstRun = true;
                $('#pageNumber1').trigger('click', function () { alert('hello'); });
            }
        }
        else {
        }
    }

    function loadCB() {
        $.fn.colorbox({ width: '60%', height: '85%', inline: true, open: true, href: '#' + opts.resultsDIV });
    }

    $.fn.extend({
        gSearch: function (options) {
            var searchInst = $.data(this[0], 'gSearch');
            if (searchInst) {
                return searchInst;
            }

            searchInst = new gSearchObject($(this).attr('id'), options);
            $.data(this[0], 'gSearch', searchInst);

            return searchInst;
        }
    });
})(jQuery);
