/**
 * AjaxSearchHandler
 *
 * @author Boz
 * @classDescription Handles ajax search.
 * @params
 *
 *  url - the url that is retreived for the partial page refresh
 *  stage - the HTML element that will be updated with new data
 *
 * @css
 *
 * .filter - attached to checkboxes used as filters 
 * .searchByText - attached to form used for text search 
 * .searchByPage - attached to links <a> used for pagination i.e. <a class="searchByPage>1</a>
 * .pre - attached to pagination links used to get the previous page
 * .nxt - attached to pagination links used to get the next page
 * #searchTerm - input used for search by text
 * .sortable - attached to elements used to initiat sorting
 * .resulthover - attached to result rows on mouseover , removed on mouse out
 *
 * Assumptions:
 *
 **/

mdp.app.AjaxSearchHandler = function( target,stage, callback,isMobile, isSuppressGoogleAds ){
    /* ---[ CLASS VARIABLES ]--- */
    this.fx = $("#results");
    this.stage = stage;
    var self = this;
    var initMatchingCategories = 2;
    var windowOffsetY = 250;
    var sendReport = true;
    var reportFilter = null;
    var reportFilterVal = null;
    var enableSearch = true;
    var virgin = true;
    var mobile = false;
    var suppressGoogleAds = false;
    var searchDialogHTML = '<form class="searchFormDialog" method="post" id="searchrecipedialog" name="searchrecipedialog" action="/search/"><input type="text" value="Search for Recipes" class="searchTerm txtcol7" id="nvbsrchtxt" name="searchTerm" autocomplete="off"><input type="hidden" value="allsearch" name="searchType"><input type="image" title="Search" alt="Search" class="searchButton" id="nvbsrchbut" src="http://images.recipe.com/recipe/images/temps/button-search.gif"></form>';

    /* ---[ CONSTRUCTOR ]--- */
    function init(){
        suppressGoogleAds = isSuppressGoogleAds || false;
        mobile = isMobile || false;
        /* initialize variables */
        mdp.filterInput = {};
        if(typeof(mdp.search) == 'object'){
            mdp.search.sortBy = "";
            if(mdp.search.page == ""){mdp.search.page = 1;}
        }

        /* customize the instance of HistoryManager */
        mdp.HistoryManager.initialize({
            stateSeparator:"&",
            onStateChange:function(){
                if(window.location.hash != ""){
                    enableSearch = true;
                    virgin = false;
                    report();
                }

                if( virgin ) {
                    handleResults();
                } else {
                    search();
                }
            }
        });

        /* initialization code */
        setupEventListeners();
        toggleFilterList(); 

        enableSearch = true;



    }

    /* ---[ PUBLIC METHODS ]--- */


    /* ---[ PRIVATE METHODS ]--- */
    function search(hashParams){

        $.ajax({
            url:target + "?displayCount=true&suppressGoogleAd=" + suppressGoogleAds + "&" + buildQuery(hashParams),
            success:function(html){
                stage.html(html);
                handleResults();
                /* self.fx.height(self.fx.height()); */
            },
            beforeSend:function( ){  /*self.fx.animate( { opacity:0 },200 );*/ }
        });
    }

    function buildQuery(hashParams){
        var obj = $.extend({},mdp.search,mdp.filterInput);
        if(hashParams != null){
            $.extend(obj,hashParams);
        }
        return $.param(obj);
    }

    function handleResults(){
        /* Check the # of results */
        if(mdp.pagination.totalResults >0){
            /* Re-attach rollovers */
            attachRollOvers();

            /* Update search header */
            displayObj(mdp.search);

            /* Update pagination 1 */
            updatePagination();
        }

        /* Update filters */
        updateFilters();

        /* Update suggestions */
        updateSuggestions();

        /* Ease in animation */

        self.fx.animate({opacity:1},100, 'linear', function() {
            if(typeof(callback) == "function") {
                callback();
            }
        });

        /* adjust page height */
        if($(window).scrollTop() > windowOffsetY){
            window.scrollTo(0,windowOffsetY);
        }        
      
    }

    /* Update the filter counts */
    function updateFilters(){
        if(mdp.filterOutput != null){
            for(var i=0; i<mdp.filterOutput.length; i++){
                var li = $("#"+mdp.filterOutput[i].facetField);
                if(li.length > 0){
                    if ( mdp.filterOutput[i].numResults < 0 ){
                        li.find("span:first").html("");
                    } else {
                        li.find("span:first").html("(" + mdp.filterOutput[i].numResults + ")");
                    }
                }
            }
        }
    }

    function updatePagination(){


        /* update display items */
        if( mobile ) displayObj(mdp.pagination);


                /* update current pages style */
                $(".pages").each(function(i,el){

                    el = $(el);
                    el.empty();

                    $.each(mdp.pagination.listOfPages,function(index,item){
                        var a = $("<a>").attr({"class":"pointer searchByPage" + (index != mdp.pagination.listOfPages.length-1 ? " rightBorder" : "" )}).unbind("click").click(function(){handleSearchByPage($(this));}).html(item).appendTo(el);
                        if(item == parseInt(mdp.search.page,10)){
                            a.addClass("unlink");
                        }
                    });

                });

                /* enable/disable links */
                $(".pre").each(function(i,link){
                    if(mdp.pagination.hasPrev){
                        $(link).removeClass("disable");
                    }else{
                        $(link).addClass("disable");
                    }
                });

                $(".nxt").each(function(i,link){
                    if(mdp.pagination.hasNext){
                        $(link).removeClass("disable");
                    }else{
                        $(link).addClass("disable");
                    }
                });

    }

    function handleSearchByPage(e){
        if($(e) && !$(e).hasClass("unlink")){

            var pageNum = $(e).text();

            page([pageNum + ""]);

            mdp.HistoryManager.setValue("page",0,pageNum);
        }
    }

    function displayObj(obj){
        /* iterate obj */
        var name;
        for(name in obj){
            if(obj.hasOwnProperty(name)){
                var el = $("#"+name + "Display");
                if(el.length > 0){
                    el.html(obj[name]);
                }else{
                    el = $("." + name + "Display");
                    if(el.length > 0){
                        el.html(obj[name]);
                    }
                }
            }
        }
    }

    function attachRollOvers(){
        $("#" + self.stage.attr("id") + " tr").unbind("mouseover").mouseover( function(){ $(this).addClass("resulthover"); });
        $("#" + self.stage.attr("id") + " tr").unbind("mouseover").mouseout( function(){ $(this).removeClass("resulthover"); });
    }

    function updateSuggestions(){
        var dymd;    
        var dymc = $("#didYouMeanContainer");
        if(dymc.length > 0){
            if(typeof(mdp.suggestions) == 'object' && typeof(mdp.suggestions.suggestions) == 'object'){
                if(mdp.suggestions.suggestions.length > 0){
                    dymc.removeClass("hide");
                    dymd = $("#didYouMeanDisplay");
                    dymd.empty();
                    for(var i=0; i<mdp.suggestions.suggestions.length; i++){
                        $("<a>").attr({"href":"/search/?searchTerm="+mdp.suggestions.suggestions[i]}).html(mdp.suggestions.suggestions[i]).appendTo(dymd);
                    }
                }
            }
            else{
               dymc.addClass("hide");
            }
        }
    }

    function updateCategories(){
        if(mdp.categories.length > 0){
            var resultcategories = $("#resultcategories");
            var categoriesDisplay = $("#categoriesDisplay");
            var seemorecatlink = $("#seemorecatlink");

            if(mdp.categories.length>initMatchingCategories){
                $("#seemorecatlink").removeClass("hide");
            }
            resultcategories.removeClass("hide");
            var offset = resultcategories.first().height();
            var height = $("#resultcategories a:first").height();
            var startHeight = (height * initMatchingCategories) + offset;

            if(mdp.categories.length>initMatchingCategories){
                resultcategories.css("height",startHeight+"px");
            }

            for(var i=0; i<mdp.categories.length; i++){
                var div = new Element("div");
                $("<a>").attr({
                    "href":mdp.categories[i].virtualPath
                }).html(mdp.categories[i].name).appendTo(div);
                div.appendTo(categoriesDisplay);
            }

        }

    }

    function report(){

        if(typeof(s) == "object"){
            var pagename = "";

            /* build reporting string */
            if(reportFilter != null && reportFilterVal != null){
                pagename = "Search:Results:"+ mdp.search.page + ":" + reportFilterVal + ":" + reportFilter;
            }else{
                pagename = "Search:Results:"+ mdp.search.page;
            }

            /* set omniture values */
            s.eVar9 = pagename;
            if(typeof(sendPageEvent) == 'function'){
                sendPageEvent('',pagename);
            }
        }
    }

    function toggleCategories(){
        var resultcategories = $("#resultcategories");
        var seemorecatlink = $(this);
        var offset = resultcategories.first().height();
        var height = $("#resultcategories a:first").height();
        var startHeight = (height * initMatchingCategories) + offset;
        var endHeight = (height * mdp.categories.length) + offset;
        if(resultcategories.height() == startHeight){
            $(resultcategories).animate({"height":endHeight});
            seemorecatlink.html("Hide Categories");
        }else{
            $(resultcategories).animate({height:startHeight});
            seemorecatlink.html("See More Categories");
        }
    }

    function filterByPartner(args){
        var id = args[0];
        var el = $("#"+id);
        var elLI = el.parent();
        if (args[1] == "true"){
            elLI.addClass("on");
            elLI.removeClass("off");
            injectRemoveItem(el, id);
            attachRemoveItems();
        } else {
            elLI.addClass("off");
            elLI.removeClass("on");
            if($("#remove_" + id)){
                $("#remove_" + id).remove();
            }
        }
        mdp.filterInput[id] = (args[1] == "true")? true: false;

        sendReport = true;
        if(args[1] == "true"){
            reportFilter = id;
            reportFilterVal = "filter";
        }else{
            reportFilter = id;
            reportFilterVal = "remove";
        }
        toggleFilterList();
    }

    this.populateAd = function() {
        populateAd();
    };

    function populateAd() {
        if ( !mobile ) {
            var adSrcUrl = "/common/common/advertisement/adTypes/sponsorshipAd.jsp?sponsorshipSize=230x600";
            var match = null;
            var test = /(?:&|&amp;)?partner_([^=]+)=([^&]+)/gi;
            var hash = window.location.hash;
            var partnerArr = new Array();
            var partnerIdx=0;
            var refresh = false;
            while ( match =  test.exec(hash) ) {
                if ( match != null  ) {
                    partnerArr[partnerIdx++] = match[1];
                }
            }
            /* only filter ads if there is one partner Id... otherwise, run of site */
            if ( partnerArr && partnerArr.length == 1 && $("#partnerFilteredAd").html().indexOf(partnerArr[0]) == -1) {
                adSrcUrl += "&partnerid=" + partnerArr[0];
                refresh = true;
            } else if ( partnerArr && partnerArr.length > 1 && $("#partnerFilteredAd").html().indexOf('partnerid') > -1 ) {
                refresh = true;
            }
            if ( partnerArr && partnerArr[0] ) {
                updateSearchTermDisplay(partnerArr);
            }
            /* Inject ad iframe if the partner has changed OR there isn't currently an ad */
            if ( refresh || $("#partnerFilteredAd").html() == '' ) {
                var content = "<iframe id='adIframe' frameborder='0' scrolling='no' src='" + adSrcUrl + "' width='244' height='600'><\/iframe>";
                $("#partnerFilteredAd").html(content);
            }
        }
    }

    function updateSearchTermDisplay(partnerArr) {
        if ( partnerArr && partnerArr.length > 0 && mdp.search.searchType == 'partnerRecipes' ) {
            switch(partnerArr.length) {
                case 1:
                    var test = /(.*)\((\d*)\)/gi;
                    var partnerDivId = '#partner_' + partnerArr[0];
                    var match =  test.exec($(partnerDivId).text());
                    $('#resultinfo').text('Your search for ' + match[1] + ' found ' + match[2] + ' results');
                    break;
                default:
                    $('#resultinfo').text("");
            }
        }
    }

    function filterByIng(args){
        if (args[1] != ""){
            var id = args[0];
            var ing = unescape(args[1]);
            var action = args[2];

            var ingredientList = "";
            var otherIngredients = $("#otherIngredients" + id).val();
            if(otherIngredients == ""){
                ingredientList = ing;
            } else {
                ingredientList = otherIngredients + "," + ing;
            }
            switch (action){
                case "remove":

                if($("#remove_ing_" + ing)){

                    var type = $("#remove_ing_" + ing).attr("alt");
                    $("#remove_ing_" + ing).remove();

                    var ingredientList = $("#otherIngredients" + type).val();

                    if (ingredientList.indexOf("," + ing) > -1){
                        ingredientList = ingredientList.replace( "," + ing, "");
                    } else if (ingredientList.indexOf(ing) > -1){
                        ingredientList = ingredientList.replace(ing, "");
                    }
                    $("#otherIngredients" + type).val(ingredientList);

                    page(["1"]);

                    mdp.filterInput[id] = (ingredientList);
                    mdp.HistoryManager.setValues(type, [type, escape(ingredientList)]);
                    mdp.HistoryManager.setValue("page",0,"1");
                }

                break;
                case "removeAll":

                    $("#with_ing_list").empty();
                    $("#withOut_ing_list").empty();

                    mdp.filterInput["with"] = ("");
                    mdp.filterInput["withOut"] = ("");
                    mdp.HistoryManager.setValues("with", ["with", ""]);
                    mdp.HistoryManager.setValues("withOut", ["withOut", ""]);
                    mdp.HistoryManager.setValue("page",0,"1");

                break;

                default:
                    var ingredientList = "";
                    var otherIngredients = $("#otherIngredients" + id).val();
                    if(otherIngredients == ""){
                        ingredientList = ing;
                    } else {
                        ingredientList = otherIngredients + "," + ing;
                    }

                    $("#otherIngredients" + id).val(ingredientList);

                    mdp.filterInput[id] = (ingredientList);
                    mdp.HistoryManager.setValues(id, [id, escape(ingredientList)]);
                    mdp.HistoryManager.setValue("page",0,"1");
                    $("#ingredients" + id).val("");

                    if(ing.indexOf(",") > -1){
                        var ingList = ing.split(",");
                        for (i = 0; i <= (ingList.length - 1) ; i++){
                            injectIngredient(id, ingList[i]);
                            attachIngredient();
                        }
                    } else {
                        injectIngredient(id, ing);
                        attachIngredient();
                    }
            }

            sendReport = true;
            if(id != "remove"){
                reportFilter = id;
                reportFilterVal = "filter";
            }else{
                reportFilter = id;
                reportFilterVal = "remove";
            }
        }
    }

    function sortBy(params){
        if(params[0] == "default"){
            /*$(".sortable").removeClass("sorted");*/
            mdp.search.sortBy="";
            return;
        }
       /*
        var el = $("#"+params[0]);
        var sorted = $("#sort").find(".sorted:first");
        var parent = el.parent();
        */

        /* if(sorted.length>0){ sorted.removeClass("sorted"); } */
        /* el.addClass("sorted"); */
        mdp.search.sortBy = params[0];

        sendReport = false;
    }

    function sortDescending(params){

        var el = [];
        if( mdp.search.sortBy ) el = $("#"+mdp.search.sortBy);
        if(el.length>0){
            var parent = el.parent();

            if(params[0] == "true"){
                mdp.search.sortDescending = true;
                parent.removeClass("sortDescending");
            }
            else{
                mdp.search.sortDescending = null;
                parent.addClass("sortDescending");
            }
        }
        sendReport = false;
    }

    function page(params){

        mdp.search.page = parseInt(params[0],10);
        sendReport = true;
        reportFilter = null;
        reportFilterVal = null;
    }

        function injectRemoveItem(el, id){

            var sf = $("#selectedFilters");
            var thisLiText = el;
            thisLiText.find("span").first().empty();
            var thisLI = $("<li>").attr({
                'id': "remove_" + id
            });
            thisLI.html(thisLiText.html() + " [<span alt='" + id +"' class ='remove_filter'>remove</span>]");
            thisLI.appendTo(sf);
        }

        function attachRemoveItems(){
            $(".remove_filter").each(function(i,el){

                var thisRemoveID = $(el).attr("alt");

                /* set state on click */
                $(el).unbind('click').click(function(){
                    var thisRemove = $(this);
                    var id = thisRemove.attr("alt");
                    var value = false;

                    page(["1"]);
                    filterByPartner([id,value]);

                    mdp.HistoryManager.setValues(id, [id,value]);
                    mdp.HistoryManager.setValue("page",0,"1");

                });
            });
        }


        function injectIngredient(type, ing){

                    var ingList = $("#"+ type +"_ing_list");
                    if (ingList.length > 0){
                        var thisLiText = ing;
                        var thisLI = $("<li>").attr({
                            'id': "remove_ing_" + ing,
                            'alt': type
                        });
                        thisLI.html("<div class='floatleft'>" + thisLiText + "</div> <span alt='" + ing +"'  class ='remove_ing'></span>");
                        thisLI.appendTo(ingList);
                    }
        }

        function attachIngredient(ing, type){

            $(".remove_ing").each(function(i,el){

                var thisRemoveID = $(el).attr("alt");

                /* set state on click */
                $(el).unbind('click').click(function(){
                    var thisRemove = $(this);
                    var id = thisRemove.attr("alt");
                    var type = thisRemove.parent().attr("alt");
                    var value = false;

                    page(["1"]);
                    filterByIng([type,id,"remove"]);

                    mdp.HistoryManager.setValues(id, [id,value]);
                    mdp.HistoryManager.setValue("page",0,"1");

                });
            });
        }

        function toggleFilterList(){

            if ($("#selectedFilterList").length > 0){
                if($("#selectedFilters").children().length == 0){

                    $("#reset_filters_text").addClass("hide");
                    $("#selectedFilterList").addClass("hide");
                } else {
                    $("#reset_filters_text").removeClass("hide");
                    $("#selectedFilterList").removeClass("hide");
                }
            }

        }

    this.refreshEventListeners = function(){
        refreshEventListeners();
    };

    function refreshEventListeners(){

        $( ".searchByPage" ).unbind( "click" ).click( function( ){ handleSearchByPage( this ); } );

        $(".pre").unbind("click").click(function(){
            if(mdp.pagination.hasPrev){
                page([parseInt(mdp.search.page,10) - 1 + ""]);
                mdp.HistoryManager.setValue("page",0,mdp.search.page);
            }

        });

        $(".nxt").unbind("click").click(function(){
            if(mdp.pagination.hasNext){
                page([parseInt(mdp.search.page,10) + 1 + ""]);
                mdp.HistoryManager.setValue("page",0,mdp.search.page);
            }
        });


        $( ".sortable ").unbind('click').click( function( ) {
            /*e.preventDefault();*/
            var el = $( this );
            var sorted = $( "#sort .sorted:first" );
            var parent = el.parent();
            /* toggle asc/desc */
            if( parent.hasClass( "sortDescending" ) ){
                if( mdp.search.sortBy != "" && mdp.search.sortBy == el.attr( 'id' ) ) {
                    sortDescending(["true"]);
                    mdp.HistoryManager.setValue("sortDescending",0,"true");
                } else {
                    sortBy([el.attr('id')]);
                    mdp.HistoryManager.setValue("sortBy",0,el.attr('id'));
                }
            }
            else{
                if(mdp.search.sortBy != "" && mdp.search.sortBy == el.attr('id')) {
                    sortDescending(["false"]);
                    mdp.HistoryManager.setValue("sortDescending",0,"false");
                } else {
                    sortBy([el.attr('id')]);
                    mdp.HistoryManager.setValue("sortBy",0,el.attr('id'));
                }
            }
        });



        $(".recipeSearchSortBox").change(function( e ){
            var selectedValue = $(this).children("option:selected").val();

            sortBy([selectedValue]);
            mdp.HistoryManager.setValue("sortBy",0,selectedValue);

        });

        $(".recipeSearchSortBox").val(mdp.search.sortBy);

        $("#seemorecatlink").click(toggleCategories);


        $("#startNewSearch").unbind('click').click(function(){
            new mdp.app.Dialog(searchDialogHTML,{position:"top",offsetY:300,width:400,height:50});

            mdp.searchrecipedialog = $("#searchrecipedialog");

            mdp.ac_dialog = new mdp.app.AutoComplete(mdp.searchrecipedialog,RecipeComAutocompleteService.getTerms);

        });


        attachRollOvers();
    };

    /* ---[ EVENT LISTENERS ]--- */
    function setupEventListeners(){

        $(".filter").each(function(i,el){
            /* setup states for each filter */
            /* setup states for each filter */
            mdp.HistoryManager.register(el.id,[el.id,"false"],
                filterByPartner,
                function(params){
                    return params[0] + "=" + params[1];
                },
                '('+ el.id +')=(true|false)'
            );

            /* set state on click */
            $(el).unbind('click').click(function(){

                var filter = $(this);
                var filterLI = $(this).parent();
                var id = filter.attr("id");
                filterLI.toggleClass("on");
                var value = (filterLI.hasClass("on"))?"true":"false";
                page(["1"]);
                filterByPartner([id,value]);
                mdp.HistoryManager.setValues(id, [id,value]);
                mdp.HistoryManager.setValue("page",0,"1");
            });

            /* populate filterInput object */
            mdp.filterInput[el.id] = ($(el).parent().hasClass("on"))? true:false;
        });

        mdp.HistoryManager.register("page",["1"],
            page,
            function(params){
                return "page=" + params[0];
            },
            /page=(\d+)/

        );


        mdp.HistoryManager.register("sortBy",["default"],
            sortBy,
            function(params){
                return "sortBy=" + params[0];
            },
            "sortBy=" + '(name|prepTime|totalTime|ratingAvg)'
        );

        mdp.HistoryManager.register("sortDescending",["false"],
            sortDescending,
            function(params){
                return "sortDescending=" + params[0];
            },
            "sortDescending=" + '(true|false)'
        );


        $("#reset_filters").unbind('click').click(function(){

            $(".remove_filter").each(function(i,el){
                var id = $(el).attr("alt");
                var value = false;

                page(["1"]);
                filterByPartner([id,value]);

                mdp.HistoryManager.setValues(id, [id,value]);
                mdp.HistoryManager.setValue("page",0,"1");

            });

            filterByIng(["with","removeAll","removeAll"]);

        });

        $('div.filterWith div[type="withOut"]').attr('type','with');

         $(".ingredientsButton").each(function(i,el){

            var type = $(el).attr("type");

             $(el).unbind('click').click(function(){

                var type = $(el).attr("type");
    
                var thisIngredient = $("#ingredients" + type).val();

                page(["1"]);
                filterByIng([type,thisIngredient,"add"]);
            });

            mdp.HistoryManager.register(type,[type,""],
                filterByIng,
                function(params){
                    return params[0] + "=" + params[1];
                },
                '(' + type + ')=([A-z0-9, %]+)'
            );

        });

        refreshEventListeners();
        mdp.HistoryManager.start();


    }

    /* ---[ RUN ]--- */
    init();
};

/* temporary fix */
   if( !window.refreshAdFrame ) var refreshAdFrame = function(){};

