

// -----------------------------------------------------------------------------
//  AUTOCHOOSER
// -----------------------------------------------------------------------------

'Ajax.Autochooser'.namespace({
  
  /**
   * Inits (lazy) all elements matching DIV.DataChooser INPUT.formChooserLabelfield.
   * Inits all TreeCats.
   * 
   * @see Ajax.Autochooser._initElement
   */
  initChoosers: function(){
    var t0 = new Date().getTime();
    
    // Create div to populate
    Ajax.Autochooser._initAutoCompleteDIV();
    
    Event.observe(document, 'jcms:focus',     Ajax.Autochooser._initChoosersLazy);
    
    // TreeCat
    $$('UL.TreeCat').each(function(elm,idx){
      Ajax.Autochooser._initTreecat(elm);
    });
    
    var t1 = new Date().getTime();
    JcmsLogger.info('Autochooser', 'Init Autochooser Manager', ' in '+(t1-t0)+' ms');
  },

  _initAutoCompleteDIV: function(){
    
    if (Ajax.Autochooser.autoCompleteDivId){ return; }
    
    var acDiv = $(document.createElement('DIV'));
    acDiv.addClassName('autocomplete');
    document.body.appendChild(acDiv);
  
    Ajax.Autochooser.autoCompleteDivId = acDiv.identify();
  },

  _initFragment: function(event){ 
  
    // Create div to populate
    Ajax.Autochooser._initAutoCompleteDIV();
  
    // Init part of the 
    var fragment = JCMS.ajax.Refresh.getFragment(event);
    if (!fragment){ return; }
    
    fragment.select('UL.TreeCat').each(function(elm,idx){
      Ajax.Autochooser._initTreecat(elm);
    });
  },
  
  _disposeFragment: function(event){
    var fragment = JCMS.ajax.Refresh.getFragment(event);
    if (!fragment){ return; }
    /* empty */
  },
  
  // --------------------------------------------------
  //  INIT FUNCTIONS
  // --------------------------------------------------
  
  /**
   * Lazy initialisation of Aucompleter. 
   * Called only on click on the input
   * 
   * @param elm the clicked input
   */
  _initChoosersLazy: function(event){

    var input  = $(event.memo.elmId);
    var widget = input.fastUp(['DIV','SPAN'],'DataChooser',true,5);
    
    if (!widget || input.retrieve('_initChooser',false) || input.hasClassName("disabled")){ return; }
    
    input.store('_initChooser',true);
    input.disabled = '';
    input.writeAttribute('autocomplete','off');
    input.addClassName('autocomplete');
    
    JcmsLogger.info("Autochooser","Init Autochooser Lazy");
        
    // Retrieve Chooser type
    var type = widget.className.match(/UI_EDITOR_\S+/);
    if (!type){
      return;
    }
    
    // Init the right autocompleter
    if ('UI_EDITOR_PUBLICATIONCHOOSER' == type){
      Ajax.Autochooser._initPublications(input, widget);
    } else if ('UI_EDITOR_PUBLICATIONSCHOOSER' == type){
      Ajax.Autochooser._initPublications(input, widget, ',');
    } else if ('UI_EDITOR_CATEGORYCHOOSER' == type){
      Ajax.Autochooser._initCategories(input, widget);
    } else if ('UI_EDITOR_CATEGORIESCHOOSER' == type){
      Ajax.Autochooser._initCategories(input, widget, ',');
    } else if ('UI_EDITOR_GROUPCHOOSER' == type){
      Ajax.Autochooser._initGroups(input, widget);
    } else if ('UI_EDITOR_GROUPSCHOOSER' == type){
      Ajax.Autochooser._initGroups(input, widget, ',');
    } else if ('UI_EDITOR_MEMBERCHOOSER' == type){
      Ajax.Autochooser._initMembers(input, widget);
    } else if ('UI_EDITOR_MEMBERSCHOOSER' == type){
      Ajax.Autochooser._initMembers(input, widget, ',');
    } else if ('UI_EDITOR_WORKSPACECHOOSER' == type){
      Ajax.Autochooser._initWorkspace(input, widget);
    } else if ('UI_EDITOR_ACLCHOOSER' == type){
      Ajax.Autochooser._initAcl(input, widget);
    }
  },
  
  /**
   * Init all publication choosers
   */
  _initPublications: function(input, field, token){
    var type = Ajax.Autochooser._getChooserContentType(field);
    
    // Debug
    if (JcmsLogger.isDebug && JcmsLogger.Autochooser){
      var inputName = input.next('INPUT.formChooserfield').name;
      JcmsLogger.debug("Autochooser",inputName+" Type:",type);
    }
    
    Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acpublication.jsp?type="+type, token);
  },
  
  /**
   * Init all member choosers
   */
  _initMembers: function(input, field, token){
	  
    // Compute additional parameters from css options
	var queryParams = '';
    if (field.hasClassName('adminOnly')){
      queryParams += 'admin=true&';
    }
    if (field.hasClassName('workerOnly')){
      queryParams += 'worker=true&';
    }
    if (field.hasClassName('jstoreOnly')){
      queryParams += 'jstore=true&jcmsdb=false&';
    }
    
    // Retrieve the enclosing div groups
    var gids = Ajax.Autochooser._getChooserGroups(field); 
    
    // Debug
    if (JcmsLogger.isDebug && JcmsLogger.Autochooser){
      var inputName = input.next('INPUT.formChooserfield').name;
      JcmsLogger.debug("Autochooser",inputName+" Groups:",gids);
    }
    
    Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acmember.jsp?" + queryParams + gids, token);
  },
  
  /**
   * Init all groups choosers
   */
  _initGroups: function(input, field, token){

    // Retrieve the enclosing div groups
    var gids = Ajax.Autochooser._getChooserGroups(field); 
    var wsid = Ajax.Autochooser._getChooserWorkspace(field);
    
    // Debug
    if (JcmsLogger.isDebug && JcmsLogger.Autochooser){
      var inputName = input.next('INPUT.formChooserfield').name;
      JcmsLogger.debug("Autochooser",inputName+" Groups:",gids);
      JcmsLogger.debug("Autochooser",inputName+" Workspace:",wsid);
    }
    
    var params = "" + gids;
    if (!params.blank()) {
    	params = "&amp;";
    }
    
    params += wsid
    
    Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acgroup.jsp?"+params, token);
  },
  
  /**
   * Init all category choosers
   */
  _initCategories: function(input, field, token){
    var widget  = JCMS.form.Widget.getWidget(input);
    var params  = '';
    
    // TODO: Allow more than once
    var rootCat = widget.fastClassMatch(/rootCat_([\w\.]+)/);
    if (rootCat){ params = "rootCids=" + rootCat + "&"; }
    
    var acadd = widget.fastClassMatch(/acadd_([\w\.]+)/);
    if (acadd){ params += "acadd=" + acadd; }
    
    if (!params.blank()){ 
      params = '?'+params; 
    }
    Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/accategory.jsp"+params, token);
  },
  
  /**
   * Init all workspace choosers
   */
  _initWorkspace: function(input, field){
    Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acworkspace.jsp");
  },
  
  /**
   * Init all ACL choosers
   */
  _initAcl: function(input, field){
    Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acacl.jsp");
  },
  
  /**
   * Instanciate a new Scriptaculous AJAX Autocompleter
   */
  _newAutocompleter: function(input, url, token){
    
    // Autocomplete => DOM so DOM must not reference Autocomplete
    var ac = new Ajax.Autocompleter(input,Ajax.Autochooser.autoCompleteDivId, url, { paramName: 'autocomplete', 
                                                                             minChars: 2, 
                                                                             callback: Ajax.Autochooser._clean, 
                                                                             afterUpdateElement: Ajax.Autochooser._populate, 
                                                                             parameters: 'token=true', 
                                                                             onShow: Ajax.Autochooser._onShow,
                                                                             onHide: Ajax.Autochooser._onHide,
                                                                             tokens: token });
    input.store('jcms.autocompleter',ac);
  },
  
  _onHide: function(element, update){ new Effect.Fade(update,{duration:0.10}) },
  _onShow: function(element, update){
    
    // Store the current input
    update.store('jcms.acinput',element.identify());
    if(!update.style.position || update.style.position=='absolute') {
      update.style.position = 'absolute';
      Position.clone(element, update, {
        setHeight: false,
        offsetTop: element.offsetHeight + (Prototype.Browser.IE ? document.viewport.getScrollOffsets()[1] : 0)
      });
    }
    
    Effect.Appear(update,{duration:0.10});
  },
  
  relocate: function(){
    var acDiv = $(Ajax.Autochooser.autoCompleteDivId);
    if (!acDiv) return;
    if (acDiv.style.display=='none'){ return; }
    
    var acInput = $(acDiv.retrieve('jcms.acinput'));
    if (!acInput){ return; }
    
    var lastAC = acInput.retrieve('jcms.autocompleter');
    if (!lastAC){ return; }
    
    Ajax.Autochooser._onShow(acInput, acDiv);
  },
  
  /**
   * Init all treecat
   */
  _initTreecat: function(elm){
    
	  elm = $(elm);
	  
	  // Treecat must declare "autocomplete" class
	  if (!elm.hasClassName('autocomplete')){
	    return;
	  }
	  
	  // Check texfield doesn't already exists
	  var tfId = elm.id+'_autocomplete';
	  var tf = $(tfId);
	  if (tf){
	   tf.value = I18N.glp('info.msg.autocomplete');
	   return;
	  }
	  
	  // Create textfield for autocompleter
	  var textfield      = document.createElement("INPUT");
	  textfield.type      = 'text';
	  textfield.className = 'formTextfield autocomplete treecatcomplete';
	  textfield.treecat   = elm.id;
	  textfield.value     = I18N.glp('info.msg.autocomplete');
	  textfield.id        = tfId;
	  
	  // Append textfield before TreeCat
	  elm.parentNode.insertBefore(textfield, elm);
	  
	  Event.observe(textfield, 'focus', function(){ 
	    textfield.value = ""; 
	  });
	  
	  var uri = 'jcore/autocomplete/accategory.jsp?acadd=false&rootCids='+elm.getJcmsIds().join('&rootCids=');
	  
	  // Check filter editmode otherwise it is read mode
	  uri += elm.hasClassName('filter') ? '&filter=true' : '';
	  
	  // Check selectable
	  uri += elm.hasClassName('selectable') ? '&selectable=true' : '';
	  
	  // Check rootDisplay
    uri += elm.hasClassName('rootDisplay') ? '&rootDisplay=true' : '';
	  
	  // Check Removed/Disabled Set
    uri += "&rm="+elm.getJcmsIds('RM_').join('&rm=');
	  
	  
	  // Bind an ajax autocompleter
	  var ac = new Ajax.Autocompleter(textfield,Ajax.Autochooser.autoCompleteDivId, uri, { 
	    paramName: 'autocomplete', 
	    minChars: 2, 
	    callback: Ajax.Autochooser._clean, 
	    onShow: Ajax.Autochooser._onShow,
      onHide: Ajax.Autochooser._onHide,
	    afterUpdateElement: Ajax.Autochooser._populateTreeCat 
	  });
    $(textfield).store('jcms.autocompleter',ac);
  },
  
  // --------------------------------------------------
  //  CLASS PARSING FUNCTIONS
  // --------------------------------------------------
  
  /**
   * Parses classes of the given field to look for
   * the publication chooser type.
   * 
   * The matching classes should be super_PType (ie super_Article).
   * This classe is generated by the widget.
   * 
   * @param field the enclosing DIV
   * @return String the JCMS type of the chooser
   */
  _getChooserContentType: function(field){
    var type  = field.className.match(/super_\S+/);
    if (!type){
      JcmsLogger.warn("Autochooser","Missing Publication chooser type");
      return;
    }
    return type.toString().substr(6);
  },
  
  /**
   * Parses classes of the given field to look for
   * parameter gids (parent groups id).
   * 
   * The matching classes should be gids_GroupId (ie gids_c_1234).
   * This classe is generated by the widget parsing chooserQS.
   * 
   * @param field the enclosing DIV
   * @return String the JCMS parent groups of the chooser
   */
  _getChooserGroups: function(field){
    var gids  = field.className.match(/gids_\S+/g);
    if (!gids){
      return "";
    }
    var gids  = gids.join('&').replace(/gids_/g,'gids=');
    return gids;
  },
  
  /**
   * Parses classes of the given field to look for
   * parameter gids (parent groups id).
   * 
   * The matching classes should be gids_GroupId (ie gids_c_1234).
   * This classe is generated by the widget parsing chooserQS.
   * 
   * @param field the enclosing DIV
   * @return String the JCMS parent groups of the chooser
   */
  _getChooserWorkspace: function(field){
    var res  = field.className.match(/ws_\S+/g);
    if (!res){
      return "";
    }
    var ws = "ws=" + res[0].substring(3);
    return ws;
  },
  
  // --------------------------------------------------
  //  CALLBACK FUNCTIONS
  // --------------------------------------------------
  
  /**
   * 
   * @param li the item to check
   */
  _checkItem: function(input, li){
    var li = $(li);
    
    if (li.hasClassName('info')){
      input.value = I18N.glp('info.msg.autocomplete');
      return false;
    }
    
    if (li.hasClassName('nomatch')){
      input.value = I18N.glp('info.msg.autocomplete');
      return false;
    }
    return true;
  },
  
  /**
   * Callback used by Chooser Autocompleter. Called before request sent.
   * 
   * @param input the form chooser label input
   * @param li the selected LI tag
   */
  _clean: function(input, qs){
  
    // backup the last value typed
    input._ac = input.value; 
  
    var chooser = input.fastNext('INPUT','formChooserfield');
    if (chooser){
      chooser.value = '';
    }
    
    return qs;
  },
  
  /**
   * Callback used by Chooser Autocompleter. Called when a 
   * selection has been done.
   * 
   * @param input the form chooser label input
   * @param li the selected LI tag
   */
  _populate: function(input,li){
    var input = $(input);

    if (!Ajax.Autochooser._checkItem(input, li))
      return;
    
    var id = li.id.substring(5);
    var li = $(li);
    var title = li.readAttribute('title');
    
    if (li.hasClassName('_AddCategory_')){
      Ajax.Autochooser._addCategory(input, li);
      return;
    }
    
    var match = li.className.match(/_Skip_(\d+)_/)
    if (match){
      input.value = input._ac;
      
      (function(){
        var ac  = input.retrieve('jcms.autocompleter',ac);
        var def = ac.options.defaultParams;
        ac.options.defaultParams = def + "&skip="+match[1];
        ac.activate();
        ac.options.defaultParams = def;
      }).delay(0.5);
      
      return;
    }
    
    Ajax.Autochooser._setupChooser(input, title, id);
  },
  
  _setupChooser: function(input, lbl, id){
    
    if (lbl){
      input.value = lbl;
    }
    
    // Keyword
    JCMS.form.Widget.resizeKeyword(input);
    
    var chooser = input.fastNext('INPUT','formChooserfield');
    chooser.value = id;
    
    // Add
    if (JCMS.form.Widget.isInKeyword(input) && !input.value.blank()){
      JCMS.form.Widget.add(input);
    }
  },
  
  /**
   * Callback used by TreeCat Autocompleter. Called when a 
   * selection has been done.
   * 
   * @param input the form chooser label input
   * @param li the selected LI tag
   */
  _populateTreeCat: function(input,li){
    var input = $(input);
    
    var match = li.className.match(/_Skip_(\d+)_/)
    if (match){
      input.value = input._ac;
      
      (function(){
        var ac  = input.retrieve('jcms.autocompleter',ac);
        var def = ac.options.defaultParams;
        ac.options.defaultParams = def + "&skip="+match[1];
        ac.activate();
        ac.options.defaultParams = def;
      }).delay(0.5);
      
      return;
    }
    
    if (!Ajax.Autochooser._checkItem(input, li))
      return;
      
	  input.value = I18N.glp('info.msg.autocomplete.done');
	  input.addClassName('treecatrefresh');
	  input.blur();
	  
	  setTimeout(function(){
      input.value = I18N.glp('info.msg.autocomplete');
      input.removeClassName('treecatrefresh');
    },2000);
	  
	  Ajax.Tree.refresh(input.treecat, li.id.substring(5), true);
  },


  // --------------------------------------------------
  //  ADD FUNCTIONS
  // --------------------------------------------------

  _addCategory: function(input, li){
    var url    = JcmsJsContext.getContextPath()+'/jcore/autocomplete/ajaxcategory.jsp';
    var params = 'autocomplete='+encodeURIComponent(input._ac)+'&root='+li.id.substring(5);
    
    Ajax.performAjaxRequest(url,params,function(returnValue){
      var message = returnValue.responseText;
      if (!message){
        /* Problème de connexion */
        alert('Connexion error');
        return;
      }
      if (message.startsWith('ERROR: ')){
        alert(message.substring(7));
        Ajax.Autochooser._setupChooser(input, '', '');
        return;
      }
      Ajax.Autochooser._setupChooser(input, input._ac, message);
    });
  }
});


// -----------------------------------------------------------------------------
//  INITIALISATION
// -----------------------------------------------------------------------------

  Event.observe(window,   'load' ,  function(){ Ajax.Autochooser.initChoosers.defer() }, false);
  Event.observe(window,   'resize', function(){ Ajax.Autochooser.relocate.defer() });
  Event.observe(window,   'scroll', function(){ Ajax.Autochooser.relocate.defer() });
  Event.observe(document, 'refresh:after',  Ajax.Autochooser._initFragment,     false);
  Event.observe(document, 'refresh:before', Ajax.Autochooser._disposeFragment , false);


