﻿//
// INSTANT (AND ON-CLICK) SEARCH VIA GOOGLE SEARCH API
// © COPYRIGHT 2010 FREDRIK HANSSON
//

(function ($) {
    $.fn.InstantSearch = function (options) {
        var defaults = {
            //general
            siteurl: "", 									// string       url to the site you wish to search. null = THE INTERNET
            perpage: 5, 										// integer      results per page (8 max)
            shownohits: 500, 								// integer      milliseconds before "no this found" is shown - should be slightly higher than "instanttime"
            showresults: "onboth", 							// string       results should be shown "onboth" (both instant & onload after "enter", "oninstant" (only instant search), "onload" (only on load after "enter")
            searchfieldwidth: 557, 							// integer      width of searchfield

            //instant functionality specifically
            instanttime: 300, 								// integer      milliseconds after stopped typing that instant results are fetched
            instantfadeintime: 300, 							// integer      milliseconds to fadein/fadeout instant searchbox (and fadeout background if chosen)
            fadebackground: true, 							// true/false   should background be faded out when instant results are shown?
            resultsonfocus: false, 							// true/false   should instant search be made when searchfiled is focused (and value > 0)
            trackinstantsearches: true, 						// true/false   track instant searches 
            tracksearchurl: "tracksearch.html", 				// string       url to run GA script for instant search tracking
            instantframewidth: 382, 							// integer      width of instant seearchresults frame
            instantsearcharrow: "/BluerangeEasy/templates/1003/images/instantsearchblockarrow.gif", // string       url for arrow of instantsearchframe ("" = no arrow)
            searchfieldtext: "ange din sökfras", 			// string   	searchfield "helptext" before entering query ("" = no text)

            //pageresult functionality specifically
            pageframewidth: 600, 							// integer      width of reults shown on "enter"
            trackonloadsearches: true, 						// true/false   track onload searches 
            onloadheader: "Sökresultat för [1]"					// string   	header text onload after search 
        }

        //rework the vars a bit...
        var options = $.extend(defaults, options);
        if (options.siteurl.length > 0) { options.siteurl = "site:" + options.siteurl + " "; }

        // globals vars
        var BASIC_GOOGLE_SEARCH_URL = "http://ajax.googleapis.com/ajax/services/search/web";
        var startsearch = 0;
        var currentsearchval = "";

        //get to it!
        $(document).ready(function () {
            createelements();
            setfieldfunctionality();
            onloadjquery();
        });

        function createelements() {


            //create delayframe for delayfunctionality
            $("<div></div>").attr("id", "delayframe").appendTo($("body"));

            if (options.fadebackground == true && (!($.browser.msie && $.browser.version.substr(0, 1) <= 6))) {
                //create darkframe
                $("<div></div>").attr("id", "SEARCH_darkframe").css("opacity", 0.35).appendTo($("body"));
            }

            //create instantsearch field
            //$("<input />").attr("type", "text").attr("id", "searchfield").attr("alt", options.searchfieldtext).css("width", options.searchfieldwidth).appendTo($("body"));

            if (options.showresults == "onboth" || options.showresults == "oninstant") {
                //create instantsearch frame
                var instantframe = $("<div></div").attr("id", "SEARCH_instantsearchframe").css("width", options.instantframewidth);
                $("<div></div").attr("id", "instantsearchresults").appendTo(instantframe);

                if (options.instantsearcharrow.length > 0) {
                    $("<img/>").attr("src", options.instantsearcharrow).addClass("blockarrow").appendTo(instantframe);
                }
                instantframe.appendTo($("body"));
            }
            if (options.showresults == "onboth" || options.showresults == "onload") {
                //add onload resultframe
                //                var searchframe = $("<div></div>").addClass("instantsearchframe");
                //                var pageresultsframe = $("<div></div>").attr("id", "pageresultsframe").css("width", options.pageframewidth).appendTo(searchframe);
                //                var pageresults = $("<div></div>").attr("id", "pageresults").appendTo(pageresultsframe);
                //                searchframe.appendTo($("#InstantSearch"));
            }
            positionelements();
        }

        function setfieldfunctionality() {
            if (options.searchfieldtext.length > 0) {
            }
        }

        function positionelements() {
            //dark frame
            $("#SEARCH_darkframe").width($(document).width());
            $("#SEARCH_darkframe").height($(document).height());

            //searchbox
            //$("#searchfield").css("top", searchoffset.top);
            //$("#searchfield").css("left", searchoffset.left);

            //instantsearchresults
            //$("#SEARCH_instantsearchframe").css("top", searchoffset.top);
            var returnoffset = setSearchframeOffset();
            $("#SEARCH_instantsearchframe").css("left", returnoffset.left);
        }

        function setSearchframeOffset() {
            var searchoffset = $("#InstantSearch").offset();
            var returnoffset = {left: 0, top: 0};

            if ($.browser.safari) {
                returnoffset = { left: parseInt(searchoffset.left - 354) }
            } else if ($.browser.webkit) {
                returnoffset = { left: parseInt(searchoffset.left - 354) }
            } else if ($.browser.mozilla) {
                returnoffset = { left: parseInt(searchoffset.left - 338) }
            } else if ($.browser.msie && $.browser.version.substr(0, 1) <= 6) {
                returnoffset = { left: parseInt(searchoffset.left - 338) }
            } else if ($.browser.msie) {
                returnoffset = { left: parseInt(searchoffset.left - 338) }
            }

            return returnoffset;
        }
        function onloadjquery() {
            //show searchresults onload?
            if (options.showresults == "onboth" || options.showresults == "onload") {

                var query;
                if (options.trackonloadsearches == true) {
                    query = getUrlVars()["searchquery"];
                } else {
                    query = getUrlVars()["searchquerynotrack"];
                }
                if (query == null) {
                    query = getUrlVars()["searchquerynotrack"];
                }

                if (query != null && query.length > 0) {
                    query = cleancharacters(query);
                    $("#searchfield").val(query);
                    $('#searchfield').addClass("searching");
                    currentsearchval = query;
                    dosearch(options.siteurl + query, true, false);
                }
            }

            searchfieldfunctions();

            $(window).resize(function () {
                positionelements();
            });

            //hide the instantsearch frame
            $("#SEARCH_instantsearchframe, #searchfield").mouseup(function () {
                return false;
            });
            $(document).mouseup(function (e) {
                $("#SEARCH_instantsearchframe").fadeOut(options.instantfadeintime);
                $("#SEARCH_darkframe").fadeOut(options.instantfadeintime);
                $("body").removeClass("hideoverflow");
                if (options.fadebackground == true) {
                    $("#SEARCH_instantsearchframe").removeClass("ontopframe");
                    $("#searchfield").removeClass("ontop");
                }
            });
        }

        function searchfieldfunctions() {
            //reload to resultpage? 
            $("#searchfield").keydown(function (e) {
                if (e.keyCode == 13 && $(this).val().length > 0 && (options.showresults == "onboth" || options.showresults == "onload")) {
                    reloadpage($(this).val());
                } else if (e.keyCode == 13) {
                    startsearch = 0;
                    onsearchfield($(this).val());
                }
            });

            $("#searchbutton").click(function (e) {
                e.preventDefault();
                var searchquery = $("#searchfield").val();
                if (searchquery.length > 0 && searchquery != $("#searchfield").attr("alt")) {
                    window.location = "/sok/?searchquery=" + searchquery;
                } else {
                    alert("Du måste ange en sökfras");
                }
            });

            $("#searchform").submit(function (e) {
                e.preventDefault();
                var searchquery = $("#searchfield").val();
                if (searchquery.length > 0 && searchquery != $("#searchfield").attr("alt")) {
                    window.location = "/sok/?searchquery=" + searchquery;
                } else {
                    alert("Du måste ange en sökfras");
                }
            });


            if (options.showresults == "onboth" || options.showresults == "oninstant") {
                //show instant searchresults 
                $("#searchfield").keyup(function (e) {

                    if (e.keyCode == 37 || e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 40) {
                        //do nothing, they are just using the arrow-keys
                    } else {
                        startsearch = 0;
                        onsearchfield($(this).val());
                    }
                });

                if (options.resultsonfocus == true) {
                    $("#searchfield").focus(function () {
                        onsearchfield($(this).val());
                    });
                }

                if (options.trackinstantsearches == true) { // && $("#searchfield").val() != $("#searchfield").attr("alt")
                    $("#searchfield").blur(function () {
                        //track search via google
                        $("#tempiframe").remove();
                        if ($(this).val() != $(this).attr("alt") && $("#searchfield").val().length > 0 && $("#searchfield").val() != currentsearchval) {
                            currentsearchval = $("#searchfield").val().toLowerCase();
                            var tempiframe = $("<iframe />").attr("id", "tempiframe").css("display", "none").css("width", 1).css("height", 1).attr("src", options.tracksearchurl + "?searchqueryinstant=" + currentsearchval).appendTo($("body"));
                        }
                    });
                }
            }
        }

        function cleancharacters(frase) {
            var str;
            str = decodeURI(frase);

            return str;
        }

        function reloadpage(query) {
            var currenturl = "/sok/";
            var newurl;
            var getvar;
            getvar = "searchquery";


            if (currenturl.match("searchquery")) {
                //search query exists in url
                newurl = currenturl.split("?")[0] + "?" + getvar + "=" + query;
            } else {
                //no get variables, just fo for it!
                newurl = currenturl + "?" + getvar + "=" + query.toLowerCase();
            }

            window.location = newurl;
        }

        function onsearchfield(searchvalue) {
            resetinstant();
            if (searchvalue.length > 0) {
                $('#searchfield').addClass("writing");
                var query = options.siteurl + searchvalue;
                $("#delayframe").stop().animate({ height: 0 }, options.instanttime, function () {
                    $('#searchfield').removeClass("writing");
                    $('#searchfield').addClass("searching");
                    dosearch(query, false, false);
                });
            } else {
                $('#SEARCH_instantsearchframe').hide();
                $('#SEARCH_darkframe').hide();
                $("body").removeClass("hideoverflow");
                if (options.fadebackground == true) {
                    $("#searchfield").removeClass("ontop");
                    $("#SEARCH_instantsearchframe").removeClass("ontopframe");
                }
            }
        }

        function dosearch(query, onload, onclick) {
            var searchurl = BASIC_GOOGLE_SEARCH_URL + "?callback=?&v=1.0&rsz=" + options.perpage + "&start=" + startsearch + "&q=" + query;

            if (onload == true) {
                var searchurl = BASIC_GOOGLE_SEARCH_URL + "?callback=?&v=1.0&rsz=8&start=" + startsearch + "&q=" + query;
            } else {
                var searchurl = BASIC_GOOGLE_SEARCH_URL + "?callback=?&v=1.0&rsz=" + options.perpage + "&start=" + startsearch + "&q=" + query;
            }
            $.getJSON(searchurl, null, function (data) {
                getlastpages(data, query, onload, onclick);
            });
        }

        function getlastpages(data, query, onload, onclick) {
            if (data.responseData.cursor.pages != null) {
                var lastpage = data.responseData.cursor.pages.length;
                var lastpagestart = data.responseData.cursor.pages[lastpage - 1].start;
                if (onload == true) {
                    var searchurl = BASIC_GOOGLE_SEARCH_URL + "?callback=?&v=1.0&rsz=8&start=" + lastpagestart + "&q=" + query;
                } else {
                    var searchurl = BASIC_GOOGLE_SEARCH_URL + "?callback=?&v=1.0&rsz=" + options.perpage + "&start=" + lastpagestart + "&q=" + query;
                }

                $.getJSON(searchurl, null, function (lastdata) {
                    var totalitems = lastdata.responseData.cursor.estimatedResultCount;
                    createresultobject(data, onload, totalitems, onclick);
                });

            } else {
                nohits(onload);
            }
        }

        function nohits(onload) {
            $("#delayframe").stop().animate({ height: 0 }, options.shownohits, function () {
                $('#searchfield').removeClass("searching");

                if (onload == false) {
                    var resultframe = $('#instantsearchresults').empty();
                    var resultsul = $('<ul></ul>').appendTo(resultframe);
                    resultsul.append('<li class="noresult">Inga träffar, försök att ändra sökfras</li>');
                    $('#SEARCH_instantsearchframe').fadeIn(options.instantfadeintime);
                    $('#SEARCH_darkframe').fadeIn(options.instantfadeintime);
                    $("body").addClass("hideoverflow");
                    if (options.fadebackground == true) {
                        $("#searchfield").addClass("ontop");
                        $("#SEARCH_instantsearchframe").addClass("ontopframe");
                    }
                } else if (onload == true) {
                    var resultframe = $('#pageresults').empty();
                    var resultsul = $('<ul></ul>').appendTo(resultframe);
                    resultsul.append('<li class="noresult">Inga träffar, försök att ändra sökfras</li>');
                    $('#pageresultsframe').show();
                }

            });
        }

        function createresultobject(data, onload, totalitems, onclick) {
            var list = data.responseData.results;
            var resultlist = $("<ul></ul>");

            $.each(list, function (s) {
                var resultitem = $("<li></li>");
                if (s == (list.length - 1)) { resultitem.addClass("lastli"); }
                var resultlink = $("<a></a>").attr("href", list[s].url).appendTo(resultitem);
                $("<div></div>").addClass("title").html(list[s].title).appendTo(resultlink);
                $("<div></div>").addClass("text").html(list[s].content).appendTo(resultlink);

                if (onload == true) {
                    $("<div></div>").addClass("url").html(list[s].url).appendTo(resultlink);
                }

                resultitem.appendTo(resultlist);
            });
            var paginationlist = createpagination(data.responseData.cursor, totalitems);
            writeresult(resultlist, paginationlist, onload, onclick);
        }

        function createpagination(pagination, totalitems) {
            var totalpages = parseInt((totalitems / options.perpage) + 0.99);

            var paginationcontainer = $("<div></div>").addClass("paginationcontainer");
            $("<span>Sida</span>").appendTo(paginationcontainer);

            $.each(pagination.pages, function (e) {
                var pagenumber = pagination.pages[e].label;
                if (pagenumber <= totalpages) {
                    var startnumber = pagination.pages[e].start;
                    var pagelink = $("<a></a>").text(pagenumber).attr("href", "#").attr("ref", startnumber);
                    //selected page?
                    if (pagination.pages[e].start == startsearch) {
                        pagelink.addClass("selected");
                    }
                    pagelink.appendTo(paginationcontainer);
                }
            })

            return paginationcontainer;
        }

        function writeresult(resultlist, paginationlist, onload, onclick) {
            if (onload == true) {
                //writeresults in onloadframe
                writeonloadresults(resultlist, paginationlist, onclick);
            } else {
                //writeresults in instantframe
                writeinstantresults(resultlist, paginationlist, onclick);
            }
        }

        function writeonloadresults(resultlist, paginationlist, onclick) {
            $('#searchfield').removeClass("searching");
            var onloadframe = $("#pageresults");

            if (onclick == true) {
                onloadframe.children("ul").remove();
                resultlist.prependTo(onloadframe);
                $("#pageresults .paginationcontainer").empty();
                $("#pageresults .paginationcontainer").html(paginationlist.html());
            } else {
                $("#pageresultsframe h1").remove();
                $("<h1></h1>").html('Sökresultat för <i>"' + $("#searchfield").val() + '"</i>').prependTo($("#pageresultsframe")); // på <i> + options.siteurl + "</i>"))
                resultlist.appendTo(onloadframe);
                paginationlist.appendTo(onloadframe);
            }

            $(".searchframeload").css("height", $("#pageresultsframe").outerHeight() + 20);

            $("#pageresultsframe").show();
            paginationfunctions("#pageresults .paginationcontainer a", true, onclick);

            positionelements();
        }

        function writeinstantresults(resultlist, paginationlist, onclick) {
            var onloadframe = $("#instantsearchresults");
            $('#searchfield').removeClass("searching");

            var paginationlinks = new Array();
            paginationlinks = paginationlist.children("a");

            if (onclick == true) {
                onloadframe.children("ul").remove();
                if (paginationlinks.length > 1) {
                    $("#instantsearchresults .paginationcontainer").empty();
                    $("#instantsearchresults .paginationcontainer").html(paginationlist.html());
                }
            } else if (paginationlinks.length > 1) {
                paginationlist.appendTo(onloadframe);
            }



            resultlist.prependTo(onloadframe);

            if (paginationlinks.length > 1) {
                paginationfunctions("#instantsearchresults .paginationcontainer a", false, onclick);
            } else {
                $("#instantsearchresults ul").addClass("rounded3");
            }

            $("#SEARCH_instantsearchframe").fadeIn(options.instantfadeintime);
            $("#SEARCH_darkframe").fadeIn(options.instantfadeintime);
            $("body").addClass("hideoverflow");
            if (options.fadebackground == true) {
                $("#searchfield").addClass("ontop");
                $("#SEARCH_instantsearchframe").addClass("ontopframe");
            }


        }

        function paginationfunctions(containerstr, onload, onclick) {
            $(containerstr).click(function (e) {
                e.preventDefault();
                $("#searchfield").addClass("searching");
                var page = $(this).attr("ref");
                var query = $("#searchfield").val();
                startsearch = page;

                if (onload == true) {
                    var query;
                    if (options.trackonloadsearches == true) {
                        query = getUrlVars()["searchquery"];
                    } else {
                        query = getUrlVars()["searchquerynotrack"];
                    }
                    dosearch(options.siteurl + query, onload, true);
                } else {
                    dosearch(options.siteurl + query, onload, true);
                }

            });
        }

        function resetonload() {
            $("#pageresults").empty();
        }

        function resetinstant() {
            $("#SEARCH_instantsearchframe").hide();
            $("#SEARCH_darkframe").hide();
            $("#instantsearchresults").empty();
            $("body").removeClass("hideoverflow");
            if (options.fadebackground == true) {
                $("#searchfield").removeClass("ontop");
                $("#SEARCH_instantsearchframe").removeClass("ontopframe");
            }
        }
        function getUrlVars() {
            var vars = [], hash;
            var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
            for (var i = 0; i < hashes.length; i++) {
                hash = hashes[i].split('=');
                vars.push(hash[0]);
                vars[hash[0]] = hash[1];
            }
            return vars;
        }

    }

})(jQuery);

