﻿
// ----------------------------------------------------------------------------------
//  The link between searchcontroller and individual controls. Keeps record of 
//  event subscriptions and triggers.
// ----------------------------------------------------------------------------------
function FlowController() {
    this.EventSubscriptions = new Array();
    this.Triggers = new Array();

    // ------------------------------------------------------------------------------
    //  individual controls subscribe to Flowcontroller for events from 
    //  Searchcontroller.
    // ------------------------------------------------------------------------------
    this.SubscribeEvent = function (subscriberObj, searchController, eventName, callbackMethod) {
        //debug('Flowcontroller.SubscriveEvent(sc=' + searchController.name + ", eventName=" + eventName + ')');
        //DebugAddTab();

        var r = new EventSubscription();
        r.subscriberObj = subscriberObj;
        r.eventName = eventName;
        r.method = callbackMethod;
        r.Originator = searchController;
        this.EventSubscriptions.push(r);

        //DebugRemoveTab();
    }

    // ------------------------------------------------------------------------------
    //  Register the relationship between someone who triggers an event (a control) 
    //  and searchController. This way flowcontroller will know to notify
    //  only those who subscribe to certain search controllers.
    //  A control can trigger events to more than one searchcontroller (in theory,
    //  not tested). 
    // ------------------------------------------------------------------------------
    this.RegisterTrigger = function (name, searchController) {
        //debug('Flowcontroller.RegisterTrigger(sc=' + searchController.name + ", name=" + name + ')');
        var t = new Trigger();
        t.name = name;
        t.targetObj = searchController;
        this.Triggers.push(t);
    }

    // ------------------------------------------------------------------------------
    //  Clear all criteria for all searchcontrollers which you (name) are registered
    //  as trigger for. No search is initiated.
    // ------------------------------------------------------------------------------    
    this.ClearAllCriteria = function (name) {
        for (i = 0; i < fc.Triggers.length; i++) {
            if (fc.Triggers[i].name == name) {
                fc.Triggers[i].targetObj.ClearAllCriteria();
            }
        }
    }

    // ------------------------------------------------------------------------------
    // A ControlMultiCheckbox has changed criteria. Do a search on each 
    // searchcontroller the control has a relationship with (determined via method
    // RegisterTrigger() ).
    // ------------------------------------------------------------------------------
    this.CriteriaChange_ControlMultiCheckbox = function (name, controlItemState) {
        //debug("CriteriaChange_ControlMultiCheckbox(" + name + ")" + fc.Triggers.length + " " + controlMultiCheckboxCriteria.length);

        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:"+fc.Triggers[i].name+" == "+name+" ?");
            if (fc.Triggers[i].name == name) {
                fc.Triggers[i].targetObj.SetMultiCheckboxCriteria(name, controlItemState);
                fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
            }
        }
    }

    this.CriteriaChange_Keyword = function (name, keyword) {
        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:"+fc.Triggers[i].name+" == "+name+" ?");
            if (fc.Triggers[i].name == name) {
                fc.Triggers[i].targetObj.SetCriteriaKeyword(name, keyword);
                fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
            }
        }
    }


    // ------------------------------------------------------------------------------
    // Slider value has changed. Do a search on each 
    // searchcontroller the control has a relationship with.
    // ------------------------------------------------------------------------------
    this.CriteriaChange_Publication = function (name, pubBeforeField, pubBeforeValue, pubAfterField, pubAfterValue, disableTrigger) {
        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:"+fc.Triggers[i].name+" == "+name+" ?");
            if (fc.Triggers[i].name == name) {
                //alert("FC: "+pubBeforeValue+" "+pubBeforeField);         
                fc.Triggers[i].targetObj.SetCriteria_PublicationDate(name, pubBeforeField, pubBeforeValue, pubAfterField, pubAfterValue);
                if (!disableTrigger) {
                    fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
                }
            }
        }
    }

    // ------------------------------------------------------------------------------
    // A ControlMultiLevelCheckbox has changed criteria. Do a search on each 
    // searchcontroller the control has a relationship with.
    // Parameter 'name' is the name of the control or entity which is registered as 
    // trigger.
    // ------------------------------------------------------------------------------   
    this.CriteriaChange_ControlMultiLevelCheckbox = function (name, multiCheckboxCriteria) {
        //debug("CriteriaChange_ControlMultiLevelCheckbox(" + name + ")");
        //DebugAddTab();
        var num = 0;
        for (i = 0; i < fc.Triggers.length; i++) {
            if (fc.Triggers[i].name == name) {
                num++;
                fc.Triggers[i].targetObj.SetMultiLevelCheckboxCriteria(name, multiCheckboxCriteria);
                fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
            }
        }
        if (num == 0) {
            //debug("No trigger under the name '" + name + "' was registered!");
        }
        //DebugRemoveTab();
        //debug("~CriteriaChange_ControlMultiLevelCheckbox(" + name + ")");
    }

    // ------------------------------------------------------------------------------
    // Parameters 
    // 'name':  is the name of the control or entity which is registered as 
    //          trigger.
    // 'text':  new text to search for.
    // 'diableTrigger': If true this function will not trigger a search. This is useful
    //          if for some reason you need to make several criteria changes and only 
    //          want to trigger ONE search. Set disableTrigger to false on the LAST
    //          criteria change.
    // ------------------------------------------------------------------------------
    this.CriteriaChange_Freetext = function (name, text, disableTrigger) {
        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:" + fc.Triggers[i].name + " == " + name + " ?");
            if (fc.Triggers[i].name == name) {
                fc.Triggers[i].targetObj.SetFreetextCriteria(text);
                if (!disableTrigger) {
                    fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
                }
            }
        }
    }

    // ------------------------------------------------------------------------------
    // The price range to include in search.
    // Parameters
    //  'name':     The name of the control or entity which is registered as 
    //              trigger.
    // ------------------------------------------------------------------------------     
    this.CriteriaChange_MinMaxPrice = function (name, min, max) {
        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:"+fc.Triggers[i].name+" == "+name+" ?");
            if (fc.Triggers[i].name == name) {
                fc.Triggers[i].targetObj.SetMinMaxPrice(min, max);
                fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
            }
        }
    }

    // ------------------------------------------------------------------------------
    // Parameters
    //  'name':     The name of the control or entity which is registered as 
    //              trigger.
    //  'size':     Number of results to show on one result page.
    // ------------------------------------------------------------------------------     
    this.CriteriaChange_Pagesize = function (name, size) {
        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:"+fc.Triggers[i].name+" == "+name+" ?");
            if (fc.Triggers[i].name == name) {
                fc.Triggers[i].targetObj.SetPageSize(size);
                fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
            }
        }
    }

    // ------------------------------------------------------------------------------
    // Trigger search for a searchcontroller. Call ClearAllCriteria() first if you 
    // wish to do ALL search (unless no criteria has been set so far). 
    // ------------------------------------------------------------------------------  
    this.TriggerSearch = function (searchController) {
        searchController.DoSearch(this.OnSearchResult);
    }

    // ------------------------------------------------------------------------------
    // Parameter 'name' is the name of the control or entity which is registered as 
    // trigger.
    // Parameters:
    //      name:       The name of the control or entity which is registered as trigger.
    //      sortField:  The field (one of the fields in a result document) to sort by. 
    //      dir:        "asc" or "desc".
    // ------------------------------------------------------------------------------       
    this.CriteriaChange_Sorting = function (name, sortField, dir) {
        //debug("CriteriaChange_Sorting(name=" + name + ", sortField=" + sortField + ", dir=" + dir);
        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:"+fc.Triggers[i].name+" == "+name+" ?");
            if (fc.Triggers[i].name == name) {
                //debug("Sort Criteria change '"+name+"'"); 
                fc.Triggers[i].targetObj.SetSortCriteria(sortField, dir);
                fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
            }
        }
    }

    // ------------------------------------------------------------------------------
    // Parameter 'name' is the name of the control or entity which is registered as 
    // trigger.
    // Parameters:
    //      name:       The name of the control or entity which is registered as trigger.
    //      page:       The page of a result to show. Starts from zero. 
    // 'diableTrigger': If true this function will not trigger a search. This is useful
    //          if for some reason you need to make several criteria changes and only 
    //          want to trigger ONE search. Set disableTrigger to false on the LAST
    //          criteria change.	
    // ------------------------------------------------------------------------------     
    this.CriteriaChange_Page = function (name, page, disableTrigger) {
        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:"+fc.Triggers[i].name+" == "+name+" ?");
            if (fc.Triggers[i].name == name) {
                //debug("Criteria page change '"+name+"'");

                fc.Triggers[i].targetObj.SetPage(page);
                if (!disableTrigger) {
                    fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
                }
            }
        }

    }

    // ------------------------------------------------------------------------------
    //  Fresh result from a searchcontroller. Notify all subscribers to this event 
    //  for this searchcontroller.
    // ------------------------------------------------------------------------------   
    this.OnSearchResult = function (data, searchcontroller) {
        //debug("Flowcontroller.OnSearchResult() num="+data.response.numFound+" "); 
        //alert("bla bla:"+data.Search.Query.@query);
        for (var i = 0; i < fc.EventSubscriptions.length; i++) {
            if ((fc.EventSubscriptions[i].Originator.name == searchcontroller.name) && (fc.EventSubscriptions[i].eventName == "SearchResult")) {

                //debug("'" + fc.EventSubscriptions[i].subscriberObj.name + "' has subscribed to '" + searchcontroller.name + "' to event '" + fc.EventSubscriptions[i].eventName + "'");
                fc.EventSubscriptions[i].method(data, fc.EventSubscriptions[i].subscriberObj);
            }

        }
    }

    // ------------------------------------------------------------------------------
    // Parameter 'name' is the name of the control or entity which is registered as 
    // trigger.
    // Parameters:
    //      name:       The name of the control or entity which is registered as trigger.
    //      sortField:  The field (one of the fields in a result document) to sort by. 
    //      dir:        "asc" or "desc".
    // ------------------------------------------------------------------------------       
    this.CriteriaChange_Sorting2 = function (name, value) {
        //debug("CriteriaChange_Sorting(name=" + name + ", sortField=" + sortField + ", dir=" + dir);
        for (i = 0; i < fc.Triggers.length; i++) {
            //debug("trigger:"+fc.Triggers[i].name+" == "+name+" ?");
            if (fc.Triggers[i].name == name) {
                //debug("Sort Criteria change '"+name+"'"); 
                fc.Triggers[i].targetObj.SetSortCriteria2(value);
                fc.Triggers[i].targetObj.DoSearch(this.OnSearchResult);
            }
        }
    }
}
