﻿
// ----------------------------------------------------------------------------------------
//  Constructor parameters:
//      name:           Used to generate the id of divs and HTML controls 
//                      (other words will be added to create unique id's). 
//      facetSortedFieldIds:  Array of facet field Id's. Checkboxes are sorted based on ids in this
//                      list. If null checkboxes are sorted by count (facet results).   
//      headline:       Text shown at top of control.   
//      facetFieldObjPath: String containing the path in search result to facet. String is used to get 
//                      object using reflection. Path could be something like:  
//                      data.facet_counts.facet_fields.myfacet. The format of the facet is to be like this:
//                      Index 0: "Badeshorts|44" (44 in this case being the id)
//                      Index 1: "193" (193 in this case representing number of items in this facet).
//      facetFilter:    The facet (which may be) used in Filter Query. This is used to determine
//                      which checkboxes should be checked.
// ----------------------------------------------------------------------------------------
function ControlMultiCheckbox(name, facetSortedFieldIds, headline, facetFieldObjPath, facetFilter)
{
    this.facetSortedFieldIds = facetSortedFieldIds;
    this.headline = headline;       // Headline of control.
    this.name = name;               
    this.checkboxPrefix = name+"_"; // First part of name of every checkbox in control.
    this.nameDiv = "MultiCheckbox_"+name+"Div";      // Name of div that surrounds the control.
    this.headlineDivId = "MultiCheckbox_Headline_"+name+"Div";
    this.contentDivId = "MultiCheckbox_Content_"+name+"Div";
    this.criteriaListStatus = new Array();   
    this.userManipulated=false; // user has used control at some point.
    this.resetLinkDivId = "Multicheckbox_"+name+"_Reset";
    this.resetLinkId = "Multicheckbox_"+name+"_ResetLink";
    this.facetFieldObjPath = facetFieldObjPath;
    this.facetFilter = facetFilter;
    this.textAfterCount = "";
    this.logicOperator = "AND";
    var self = this;
    
    // ------------------------------------------------------------------------------
    // [x] Item A (2[insert text])
    // [ ] Item B (2[insert text])
    // ------------------------------------------------------------------------------
    this.SetTextAfterCount = function(text)
    {
        self.textAfterCount = text;   
    }


    // ------------------------------------------------------------------------------
    // Logic operator
    // AND  or   OR
    // ------------------------------------------------------------------------------
    this.SetLogicOperator = function(operatorText) {
        self.logicOperator = operatorText;
    }
    
    // ------------------------------------------------------------------------------
    //  Search controller will receive all relevant events from this 
    //  control.
    // ------------------------------------------------------------------------------     
    this.RegisterAsTrigger = function(searchController)
    {
        fc.RegisterTrigger(self.name, searchController);
    }
       
    // ------------------------------------------------------------------------------
    //  Subscribe to event from a searchcontroller.
    // ------------------------------------------------------------------------------         
    this.SubscribeEvent = function(searchController, eventName, callback)
    {
        fc.SubscribeEvent(this, searchController, eventName, callback);
    }

    // ------------------------------------------------------------------------------
    //  Subscribe to all relevant events from a searchcontroller.
    // ------------------------------------------------------------------------------     
    this.SubscribeEvents = function(searchController)
    {
        fc.SubscribeEvent(self, searchController, "SearchResult", self.OnSearchResult); 
    }
       
    // ------------------------------------------------------------------------------
    //  Write HTML to page.
    // ------------------------------------------------------------------------------
    this.Render = function()
    {
        var temp="";  
        var criteria;
        
        // Outer div    
        temp += "<div id='"+this.nameDiv+"' class='ControlDiv MultiCheckbox'>";            
        
	temp += "<div id='"+this.headlineDivId+"' class='ControlHeadline'>";     
        temp += "<div class='FilterControlHeadlineText'>"+this.headline
        temp += "<div id='"+this.resetLinkDivId+"' class='ControlHeadlineReset'><a id='"+this.resetLinkId+"' href=''>nulstil</a></div>";

        temp += "<div class='breaker'></div>"
        temp += "</div></div>";


            temp += "<div id='"+this.contentDivId+"' class='ControlContent'>";     
            temp += "</div>";                           
        // End outer div.
        temp += "</div>";
        
        // Write HTML to page. 
        document.write(temp);    
        
        // set height of containing div. This height is the relationship between outer div height and headline height.
        //debug(jQuery("div#"+this.nameDiv).height() + " - " + jQuery("div#"+this.headlineDivId).height());
//        var headlineHeight = (jQuery("div#"+this.nameDiv).height() - jQuery("div#"+this.headlineDivId).height() )  ;
//        jQuery("div#"+this.contentDivId).height(headlineHeight);
        
        $(document).ready(function() 
        {
            $(document).bind('SearchResult', self.OnSearchResult);   
            $jq("#"+self.resetLinkId).bind("click", self.OnResetLinkClick);
        });       
                       
    }
    this.Render();

    // ------------------------------------------------------------------------------
    //  Show little reset link in header of control.
    // ------------------------------------------------------------------------------    
    this.ShowResetLink = function()
    {
        $jq("#"+self.resetLinkDivId).show();
    }
 
    // ------------------------------------------------------------------------------
    //  Hide little reset link in header of control.
    // ------------------------------------------------------------------------------       
    this.HideResetLink = function()
    {
        $jq("#"+self.resetLinkDivId).hide();
    }

    // ------------------------------------------------------------------------------
    //  User clicked on reset link. Uncheck all checkboxes and do new search.
    // ------------------------------------------------------------------------------
    this.OnResetLinkClick = function()
    {
        self.userManipulated = false; 
        $jq("#"+self.resetLinkDivId).hide();
   
        for (i=0;i<self.criteriaListStatus.length;i++)
        {
            self.criteriaListStatus[i].selected = false;
            $jq("#"+self.criteriaListStatus[i].id).attr('checked', false);         
        } 

        fc.CriteriaChange_ControlMultiCheckbox(self.name, self.criteriaListStatus, true); 
        return false;
    }
    
    
    // ------------------------------------------------------------------------------
    //  This is called when a checkbox is clicked. 
    // ------------------------------------------------------------------------------
    this.CheckboxClicked = function(event)
    {          
        for (i=0;i<=self.criteriaListStatus.length;i++)
        {                                 
            if (self.criteriaListStatus[i].id == event.data.cbName)
            {
                if ( $('#'+event.data.cbName).attr('checked') == true)  
                {
                    self.userManipulated = true;
                    self.ShowResetLink();
        
                    self.criteriaListStatus[i].selected = true;
                                       
                    debug("control '"+event.data.obj.name+"' had checkbox '"+event.data.cbName+"' checked");
                }   
                else
                {
                    debug("control '"+event.data.obj.name+"' had checkbox '"+event.data.cbName+"' unchecked");
                    self.criteriaListStatus[i].selected = false;
                    
                    // If all checkboxes are unchecked then make sure that we do not show reset link.
                    for(var i=0; i<self.criteriaListStatus.length; i++)
                    {
                        if (self.criteriaListStatus[i].selected == false)
                        {
                            self.userManipulated = false;
                            self.HideResetLink(); 
                            break;                                             
                        }    
                    }            
                }    
                break;        
            }      
        }          
        self.What();
               
        fc.CriteriaChange_ControlMultiCheckbox(self.name, self.criteriaListStatus, true);            
    }
    
    this.What = function()
    {
        for(var i=0; i<self.criteriaListStatus.length; i++)
        {
            if (self.criteriaListStatus[i].selected)
                debug("this was selected: "+self.criteriaListStatus[i].id);
        }    
    }
    
    this.ShouldCheckboxBeChecked = function(facetFieldId, list)
    {
        for (var i=0; i<list.length; i++)
        {
            //if (parseInt(list[i]) == parseInt(facetFieldId))
            if (list[i] == facetFieldId)
            {
                return true;
            }
        }    
        return false;
    }   
    
    // ------------------------------------------------------------------------------
    //  Receive search result. Update control.
    // ------------------------------------------------------------------------------
    this.OnSearchResult = function(data, _this, persistedSearch) {
        debug("ControlMultiCheckbox[" + self.name + "].OnSearchResult() Results: " + data.response.numFound);
        DebugAddTab();

        var facetFieldText; // the part of facetField before "|" which is to be the text next to checkbox.
        var facetFieldId;   // the part of facetField after "|" which is the facet id and to be used as part of the CSS id. 
        var checkboxId;     // CSS id of checkbox constructed of different things including facetFieldId.
        var num;
        var cssId;
        var found = false;
        var numDivId;
        var listFacetFields;       // same as above but made a bit more accesible,       
        var facetField;
        var facetFilter;
        var fq = data.responseHeader.params.fq;
        debug("  fq=" + fq);

        // Clear all trace of checkboxes (we'll create them again).
        $("div#" + self.contentDivId).html("");

        facetFilter = self.facetFilter;

        // ------------------------------------------------------------------------------
        //  FacetFieldCollection from searchresult is a list of facets which are included
        //  in searchresult (has hits).  We create checkboxes from these. We need to do 
        //  some string splits to get to the information. So we do this and create array 
        //  of objects to hold information.
        // ------------------------------------------------------------------------------ 
        var facetFieldsCollection;
        eval("facetFieldsCollection = " + self.facetFieldObjPath);
        listFacetFields = new Array();
        var facetField;
        for (var i = 0; i < facetFieldsCollection.length / 2; i++) {
            if (facetFieldsCollection[i * 2] != null) {
                facetField = new FacetField();
                facetField.facetFieldId = facetFieldsCollection[i * 2].split("|")[1];
                facetField.facetFieldText = facetFieldsCollection[i * 2].split("|")[0];
                facetField.facetFieldCount = facetFieldsCollection[i * 2 + 1];
                listFacetFields.push(facetField);
            }
        }

        // ------------------------------------------------------------------------------
        //  Create list of used (in query as parameter) facet field Id's. This is used 
        //  to determine if a checkbox should be checked or not.
        // ------------------------------------------------------------------------------
        debug("What facets did we search for:");
        debug("[");
        var listUsedFacetFieldIds = new Array();
        var listUsedFacetIds = new Array();
        var temp = fq.split(facetFilter + ":");
		
		//alert("split by: '"+facetFilter + ":'");	
		
        var temp2;
        for (var i = 1; i < temp.length; i++) {
            temp2 = temp[i].split(")")[0];
            if (temp2 != "*") {
			
				// After split the temp2 might contain "Medium OR ". We need to remove " OR " because in this example
				// "Medium" is the correct Id. If not the corresponding checkbox will not be shown as checked.
				if (temp2.indexOf(" "+self.logicOperator+" ") != -1) {
					temp2 = temp2.split(" "+self.logicOperator+" ")[0];
				}
							
                listUsedFacetFieldIds.push(temp2);
						
                debug("  " + temp2 + "' count=" + listUsedFacetFieldIds.length);
				
            }
        }
        debug("]");

        // ------------------------------------------------------------------------------
        //  Create checkbox for all facets which contain results.
        // ------------------------------------------------------------------------------    

        temp = "";
						
        if (self.facetSortedFieldIds != null) // sort by list
        {
            debug("create checkboxes (sort by list):");

            for (var j = 0; j < self.facetSortedFieldIds.length; j++) {
                for (var i = 0; i < listFacetFields.length; i++) {
                    if (listFacetFields[i] == null)
                        continue;

                    facetFieldText = listFacetFields[i].facetFieldText;
                    facetFieldId = listFacetFields[i].facetFieldId;
                    num = listFacetFields[i].facetFieldCount;

                    //if (parseInt(facetSortedFieldIds[j]) == parseInt(facetFieldId)) {
					// Change 16.06.2010. We check for strings instead if int's
                    if (facetSortedFieldIds[j] == facetFieldId) {
                        if (num > 0) {
                            temp += "<div style='float: left' id='div_" + self.checkboxPrefix + facetFieldId + "'>";
                            if (self.ShouldCheckboxBeChecked(facetFieldId, listUsedFacetFieldIds)) {
                                //debug("  '"+facetFieldText+"' checked");
                                self.userManipulated = true;
                                self.ShowResetLink();
                                temp += "<input style='float:left' class='MultiCheckboxInput' type='checkbox' checked id='" + self.checkboxPrefix + facetFieldId + "' />";
                            }
                            else {
                                //debug("  '"+facetFieldText+"' unchecked");
                                temp += "<input style='float:left' class='MultiCheckboxInput' type='checkbox' id='" + self.checkboxPrefix + facetFieldId + "' />";
                            }
                            temp += "<div style='float:left;' class='MultiCheckboxText'>" + facetFieldText + "</div>";
                            temp += "<div id='" + self.checkboxPrefix + facetFieldId + "_Num' class='MultiCheckboxText' style='float:left;'>&nbsp;(" + num + self.textAfterCount + ")</div>";
                            temp += "</div>";
                            temp += "<div style='clear: both'></div>";
                        }
                        else {
                            debug("  '" + facetFieldText + "' no results for facet. Don't create checkbox.");
                        }
                    }
                }
            }
        }
        else // sort by count.
        {
            debug("create checkboxes (sort by count):");

            for (var i = 0; i < facetFieldsCollection.length / 2; i++) {
                if (facetFieldsCollection[i * 2] == null)
                    continue;

                facetFieldText = facetFieldsCollection[i * 2].split("|")[0];
                facetFieldId = facetFieldsCollection[i * 2].split("|")[1];
                num = facetFieldsCollection[i * 2 + 1];

                if (num > 0) {
                    temp += "<div style='float: left' id='div_" + self.checkboxPrefix + facetFieldId + "'>";
                    if (self.ShouldCheckboxBeChecked(facetFieldId, listUsedFacetFieldIds)) {
                        debug("  '" + facetFieldText + "' checked");
                        self.userManipulated = true;
                        self.ShowResetLink();
                        temp += "<input style='float:left' class='MultiCheckboxInput' type='checkbox' checked id='" + self.checkboxPrefix + facetFieldId + "' />";
                    }
                    else {
                        debug("  '" + facetFieldText + "' unchecked");
                        temp += "<input style='float:left' class='MultiCheckboxInput' type='checkbox' id='" + self.checkboxPrefix + facetFieldId + "' />";
                    }
                    temp += "<div style='float:left;' class='MultiCheckboxText'>" + facetFieldText + "</div>";
                    temp += "<div id='" + self.checkboxPrefix + facetFieldId + "_Num' class='MultiCheckboxText' style='float:left;'>&nbsp;(" + num + self.textAfterCount + ")</div>";
                    temp += "</div>";
                    temp += "<div style='clear: both'></div>";
                }
                else {
                    debug("  '" + facetFieldText + "' no results for facet. Don't create checkbox.");
                }
            }
        }


        // add checkboxes to content div.
        $("div#" + self.contentDivId).html(temp);

        // Setup events for each checkbox. Save info and state for each checkbox for use if a checkbox is clicked. Then we
        // need to send this state to search controller.
        self.criteriaListStatus = new Array();
        var criteria;

        // This bit could probably be optimized because I do the same calculations in earlier for loop but I cannot move code up because I cannot
        // bind event before html has been written to page. The string.splits could be stored in temporary array maybe...
        for (var i = 0; i < facetFieldsCollection.length / 2; i++) {
            if (facetFieldsCollection[i * 2] == null)
                continue;

            facetFieldText = facetFieldsCollection[i * 2].split("|")[0];
            facetFieldId = facetFieldsCollection[i * 2].split("|")[1];
            num = facetFieldsCollection[i * 2 + 1];

            criteria = new ControlMultiCheckboxCriteria(self.checkboxPrefix + facetFieldId, facetFieldText, facetFieldId, false);
            criteria.facetFieldObjPath = self.facetFieldObjPath;
            criteria.facetFilter = self.facetFilter;
            criteria.selected = self.ShouldCheckboxBeChecked(facetFieldId, listUsedFacetFieldIds);
            criteria.logicOperator = self.logicOperator;
            self.criteriaListStatus.push(criteria);

            $("input#" + self.checkboxPrefix + facetFieldId).bind('click', { cbName: self.checkboxPrefix + facetFieldId, obj: self }, self.CheckboxClicked);
        }

        if (persistedSearch) {
            fc.CriteriaChange_ControlMultiCheckbox(self.name, self.criteriaListStatus, false);
        }

        DebugRemoveTab();
        debug("~ControlMultiCheckbox[" + self.name + "].OnSearchResult()");
    }      
}


