﻿

// ----------------------------------------------------------------------------------
//  In charge of doing actual searches. Enter criterias using various methods and 
//  call DoSearch(). Searchcontroller will then call you back when result is ready.
//  Parameters:
//      name:               A name you think up. 
//      searchEngineUrl:    Basic url to search engine
// ----------------------------------------------------------------------------------
function SearchController(name, searchEngineUrl)
{
    this.name = name;
    this.sortField = null;
    this.sortDir = null;
    this.page = 0;
    this.pageSize = 20; 
    this.freetext = "";
    this.minSalesPrice=null;
    this.maxSalesPrice=null;
    this.minPriceRange=null;
    this.maxPriceRange=null;
    this.MultiLevelCheckboxCriterias = new Array();
    this.MultiCheckboxCriterias = new Array();
    this.searchEngineUrl = searchEngineUrl;
    this.lastSearchUrl = null;
    this.facetQuery = null;
    var self = this;    
    
   
    // change the url to search engine. 
    this.SetSearchEngineUrl = function(url)
    {
        this.searchEngineUrl = searchEngineUrl; 
    }

    // Numbers of results to show per page.
    this.SetPageSize = function(pagesize)
    {
        this.pageSize = pagesize;     
    }
    
    // Current page in search result. Starts from zero.
    this.SetPage = function(page)
    {
        this.page = page;                          
    }     

    this.ClearAllCriteria = function()
    {
        this.criteriaSize = null;
        this.criteriaBrands = null; 
        this.freetext = "";      
        this.MultiLevelCheckboxCriterias = new Array(); 
        this.MultiCheckboxCriterias = new Array();
        this.minSalesPrice=0;
        this.maxSalesPrice=9999;
        this.sortField = null;
        this.sortDir = null;
        this.page = 0;
    }
    
    // Enter criteria from a MultiCheckbox. Name is the name of the MultiCheckbox.
    this.SetMultiCheckboxCriteria = function(name, criteria)
    {
        debug("SearchController("+this.name+").SetControlMultiCheckboxCriteria()"+criteria.length);
        this.page = 0;
        self.MultiCheckboxCriterias[name] = criteria;
    }  
    
    // Enter criteria from a MultiLevelCheckbox. Name is the name of the MultiLevelCheckbox.
    this.SetMultiLevelCheckboxCriteria = function(name, criteria)
    {
        debug("SearchController("+this.name+").SetControlMultiLevelCheckboxCriteria()");           
        self.MultiLevelCheckboxCriterias[name] = criteria;    
        debug("gemt under: "+name);                         
        this.page = 0;    
        debug("~SearchController("+this.name+").SetControlMultiLevelCheckboxCriteria()");          
    }
    
    // Freetext from user. Example: "jeans".
    this.SetFreetextCriteria = function(text)
    {
        this.freetext = text;   
    }
    
    // The price range to include in search.
    this.SetMinMaxPrice = function(min, max)
    {
        this.minSalesPrice=min;
        this.maxSalesPrice=max;
    }

    this.MinMaxPriceRange = function(minrange, maxrange)
    {
        this.minPriceRange=minrange;
        this.maxPriceRange=maxrange;
    }	
    
    this.SetSortCriteria = function(sortField, dir)
    {
        debug("SearchController["+ this.name +"](sortField="+sortField+", dir="+dir);
        this.page = 0;
        this.sortField = sortField;
        this.sortDir = dir;       
    }

    this.DoPersistedSearch = function(data, callback)
    {
        debug("SearchController[" + self.name + "].DoPersistedSearch(data:" + data + ")");
        //        /fq=([^&]+)/.exec(data);
        this.facetQuery = extractCategoriesQuery(data); //RegExp.$1;
        jQuery.getJSON(self.searchEngineUrl + data, {},
            function(json)
            {
                var num = json.response.numFound;
                callback(json, self, true);
            });
        DebugRemoveTab();
        debug("~SearchController(" + self.name + ").DoPersistedSearch()");
    }

    function extractCategoriesQuery(data)
    {
        var matches = data.match(/(\(h?cid:\/[^)]+\))/g);

        if (matches == null)
            return null;

        var categories = "";

        for (var i = 0; i < matches.length; ++i)
        {
            categories += matches[i];

            if (i + 1 != matches.length)
                categories += " OR ";
        }

        return "(" + categories + ")";
    }
    
    // create request from all criteria and send request to search engine. callback parameter is 
    // the method you want to be called with searchresult.
    this.DoSearch = function(callback) {
        debug("SearchController(" + this.name + ").DoSearch()");
        DebugAddTab();

        var _this = this;
        var url = self.searchEngineUrl;

        if (url.indexOf("?") != -1) {
            var url = url + "&fq=";
        }
        else {
            var url = url + "?fq=";
        }

        var fq = "";

        // price range
        if (self.minSalesPrice != null && self.maxSalesPrice != null) {
            fq += "sp:[" + self.minSalesPrice + " TO " + self.maxSalesPrice + "]";
        }

        for (var key in self.MultiCheckboxCriterias) {
            var tmpFq = "";
            for (var i = 0; i < self.MultiCheckboxCriterias[key].length; i++) {
                if (self.MultiCheckboxCriterias[key][i].selected) {
                    if (tmpFq != "")
                        tmpFq += " " + self.MultiCheckboxCriterias[key][i].logicOperator + " ";

                    tmpFq += "" + self.MultiCheckboxCriterias[key][i].facetFilter + ":" + self.MultiCheckboxCriterias[key][i].value + "";
                }
            }
            if (fq != "" && tmpFq != "")
                fq += " AND ";
            if (tmpFq != "")
                fq += "(" + tmpFq + ")";
        }

        if (this.facetQuery != null)
        {
            if (fq != "")
                fq += " AND ";

            fq += this.facetQuery;
        }

		/*if (window.console)
			console.log('MultiLevelCheckboxCriterias');
			*/
       for (var key in self.MultiLevelCheckboxCriterias) {
            var tmpFq = "";
            for (var i = 0; i < self.MultiLevelCheckboxCriterias[key].length; i++) {
                if (self.MultiLevelCheckboxCriterias[key][i].selected) {
                    if (tmpFq != "")
                        tmpFq += " " + self.MultiLevelCheckboxCriterias[key][i].logicOperator + " ";

                    tmpFq += "(" + self.MultiLevelCheckboxCriterias[key][i].facetFilter + ":" + self.MultiLevelCheckboxCriterias[key][i].facetPath + "*)";
                }
            }
            if (fq != "" && tmpFq != "")
                fq += " AND ";
            if (tmpFq != "")
                fq += "(" + tmpFq + ")";
        }




        if (this.sortField != null) {
            fq += "&sort=" + this.sortField + "+" + this.sortDir;
        }

        // paging
        fq += "&start=" + (this.page * this.pageSize) + "&rows=" + this.pageSize;


        url = url + fq;

        if (q != "") {
            var q = "&q=" + this.freetext;
            url = url + q;
        }

        debug("url = " + url);
        debug("fq = " + fq);

        self.lastSearchUrl = url;

        $jq.ajax({
            url: url,
            dataType: 'json',
            data: {},
            async: true,
            success: function(json) {
                var num = json.response.numFound;
                callback(json, self, false);
            }
        });

        DebugRemoveTab();
        debug("~SearchController(" + this.name + ").DoSearch()");
        return url;
    } 
}