
// -----------------------------------------------------------------------------
//  CLASS
// -----------------------------------------------------------------------------


'JCMS.form.Widget'.namespace({
  init: function(){
    setupSingleSubmitButton();
    JCMS.form.Widget._initBlurFocus();
  },

  /**
   * -----------------------------------------------------------------------------
   *  TEXTAREA RESIZER
   * -----------------------------------------------------------------------------
   */

  /**
   * Handle TextArea Resizer
   */
  _initResizer: function(event){
    var widget = $(event.memo.elmId);
    
    if (!widget || widget.tagName != 'TEXTAREA'){ return; }
    
    
    JCMS.form.Widget.autoResize(widget);
    
    if (widget.hasClassName("resizable")){ return; }
    widget.addClassName("resizable");
    
    
    Event.observe(widget,"mousedown",JCMS.form.Widget.dragStart);
    Event.observe(widget,"keypress",function(event){
      var key = event.which || event.keyCode;
      if (!key || key != Event.KEY_RETURN){ return; }
      JCMS.form.Widget.autoResize(Event.element(event));
    });
    
    // Wiki Toolbar
    var tbar = widget.next('DIV.wikitoolbar');
    if (tbar){
      tbar.style.width = widget.getWidth() - 2 + 'px';
      Event.observe(tbar,"mousedown",JCMS.form.Widget.dragStart);
    }
  },
  
  _drag    : false,
  _dragX   : 0,
  _dragY   : 0,
  _dragW   : 0,
  _dragH   : 0,
  
  dragStart : function(event) {
    
    var elm = Event.element(event);
    var x   = Event.pointerX(event)-10; /* (10) is a Hack because of tab-page padding */
    var y   = Event.pointerY(event)-10; 
    var vp  = elm.cumulativeOffset();
    var ew  = elm.getWidth();
    var eh  = elm.getHeight();
    var ex  = vp.left;
    var ey  = vp.top;

    if ((x > ex+ew) || (y > ey+eh) || (x < ex+ew-32) || (y < ey+eh-32)){
      // alert(elm.tagName+' : '+(ex+ew-32)+'<'+x+'<'+(ex+ew) +' / '+ (ey+eh-32)+'<'+y+'<'+(ey+eh));
      return;
    }
    
    elm.style.cursor= 'se-resize';
    
    // Wiki Toolbar
    if (elm.hasClassName('wikitoolbar')){
      elm = elm.previous('TEXTAREA');
      ew  = elm.getWidth();
      eh  = elm.getHeight();
    }
    
    JCMS.form.Widget._drag  = elm.identify();
    JCMS.form.Widget._dragX = x;
    JCMS.form.Widget._dragY = y;
    JCMS.form.Widget._dragW = ew;
    JCMS.form.Widget._dragH = eh;
    
    Event.observe(document, "mousemove", JCMS.form.Widget.dragMove);
    Event.observe(document, "mouseup",   JCMS.form.Widget.dragEnd);
  },
  
  dragEnd : function(event) {
    var elm = $(JCMS.form.Widget._drag);
    if (!elm){ return; }
    
    elm.style.cursor= '';
    
    // Wiki Toolbar
    var tbar = elm.next('DIV.wikitoolbar');
    if (tbar){
      tbar.style.cursor= '';
    }
    
    JCMS.form.Widget._drag  = false;
    Event.stopObserving(document, "mousemove", JCMS.form.Widget.dragMove);
    Event.stopObserving(document, "mouseup",   JCMS.form.Widget.dragEnd);
  },

  dragMove : function(event) {
    var elm = $(JCMS.form.Widget._drag);
    var x   = Event.pointerX(event);
    var y   = Event.pointerY(event);
    var w   = JCMS.form.Widget._dragW + (x - JCMS.form.Widget._dragX);
    var h   = JCMS.form.Widget._dragH + (y - JCMS.form.Widget._dragY);
    
    if (w > 15) { elm.style.width  = w + "px"; }
    if (h > 15) { elm.style.height = h + "px"; }
    
    // Wiki Toolbar
    var tbar= elm.next('DIV.wikitoolbar');
    if (w > 15 && tbar){ tbar.style.width  = w + 6 + "px"; }
  },

  autoResize : function(ta) {
    var lines = ta.value.split('\n');
    var rows = 1;
    for (i = 0; i < lines.length; i++) {
      if (lines[i].length >= ta.cols) { 
        rows += Math.floor(lines[i].length / ta.cols);
      }
    }
    rows += lines.length;
    if (rows > ta.rows) {
      ta.rows = Math.min(rows,20);
    }
  },

  /**
   * -----------------------------------------------------------------------------
   *  DRAG n DROP
   * -----------------------------------------------------------------------------
   */

  _initDragDrop: function(event){
    
    
    if (JcmsJsContext.isIE && !JcmsJsContext.isIE8){ return; }
    
    var widget = $(event.memo.elmId);
    var last   = $(event.memo.lastId);
    
    // Current
    if (!widget){ return; }
    
    // Removing last
    if (last){
      var drag = last.fastUp(['DIV','OL','UL'],null,true,10);
      if (drag && drag.hasClassName("dragdrop") && drag.tagName != "DIV"){
        if (drag == list){ return; }
        // Sortable.destroy(drag);
        drag.removeClassName("dragdrop")
      }
    }
    
    var list   = widget.fastUp(['DIV','OL','UL'],null,true,10);
    if (!list || list.hasClassName("dragdrop") || list.tagName == "DIV" || list.hasClassName('wdg-tabpane')){ return; }
    
    list.addClassName("dragdrop");
    list._draggable = list.childElements().invoke('identify'); // Store list items ids order;
    
    // Known bug: Sortable.create stop <input type='file' /> popup
    Sortable.create(list.identify(), { tag: 'LI',
                                       overlap: 'vertical',
                                       constraint: 'vertical',
                                       ghosting: false,
                                       onUpdate: JCMS.form.Widget._dndLang,
                                       handles: list.select('IMG.grip'),
                                       tree: false,
                                       treeTag: list.tagName
    });
  },

  _dndLang: function(container){
    
    //var lang  = container.fastUp('DIV','wdglang',true,4);
    //if (!lang){ return; }
    
    // Retrieve order
    var old   = container._draggable;
    var order = container.childElements().collect(function(elm){
      return old.indexOf(elm.identify());
    });
    
    // Update order
    container._draggable = container.childElements().invoke('identify'); // Store list items ids order;
    
    // Do it on all Language and all tab-groups
    JCMS.form.Widget.reorder(container.down('LI'),order);

  },
  
  _resetDragDrop: function(event){  
    var widget = $(event.memo.wrapper);
    if (!widget){ return; }
    
    if (widget.hasClassName('dragdrop')){
      // Sortable.destroy(widget);
      list.removeClassName("dragdrop");
      return;
    }
    
    var list = widget.fastUp(['DIV','OL','UL'],null,true,10);
    if (list.hasClassName('dragdrop')){
      // Sortable.destroy(list);
      list.removeClassName("dragdrop");
    }
  },

  /**
   * -----------------------------------------------------------------------------
   * BLUR / FOCUS
   * -----------------------------------------------------------------------------
   */
   
  _lastFocusId: false,
  
  _initBlurFocus: function(event){
  
    var elms  = false;
    var clear = false;
    
    if (event){ // Working on given wrapper
      var wrapper = $(event.memo.wrapper);
      if (!wrapper){ return; }
      JCMS.form.Widget._initBlurFocusElm(wrapper);
      elms  = wrapper.descendants();
      clear = true;
    }
    else if (document.forms){// Working on all forms inputs
      var forms = $A(document.forms);
      elms = [];
      forms.each(function(form, idx){
        elms.addAll(form.elements);
      });
    }
    
    if (!elms){ return; }
    
    elms.each(function(input,idx){
      JCMS.form.Widget._initBlurFocusElm(input);
    });
  },
  
  _initBlurFocusElm: function(input, clear){
    var input = $(input);
    
    var cname = input.className;
    if (clear && cname){
      if (cname.indexOf('focus-field') >= 0){  input.removeClassName('focus-field');  }
      if (cname.indexOf('focus-widget') >= 0){ input.removeClassName('focus-widget'); }
    }
    if (input.tagName != "INPUT" && input.tagName != "TEXTAREA" && input.tagName != "SELECT"){ return; }
    if (input.type && input.type == "hidden" || input.type == "button"|| input.type == "submit"){ return; }
    
    Event.observe(input, 'focus', JCMS.form.Widget.fireFocus);
    Event.observe(input, 'blur',  JCMS.form.Widget.fireBlur);
  },
  
  fireBlur: function(event){
    var input  = Event.element(event);
    var widget = JCMS.form.Widget.getWidget(input);
    if (!widget || widget.hasClassName("disabled")){ return; }
    document.fire('jcms:blur',{ elmId: input.identify() });
  },
  
  fireFocus: function(event){
    var widget   = Event.element(event);
    var lastFocus = $(JCMS.form.Widget._lastFocusId);
    
    // Do not fire twice on the same element
    if (widget == lastFocus){ return; }
    
    var wrapper1 = JCMS.form.Widget.getWrapper(widget);
    var wrapper2 = JCMS.form.Widget.getWidget(widget);
    if (wrapper2 && wrapper2.hasClassName("disabled")){
      return;
    }
    
    
    // Remove last focus
    if (lastFocus){
      var lastWrapper1 = JCMS.form.Widget.getWrapper(lastFocus);
      if (lastWrapper1){
        lastWrapper1.removeClassName('focus-field');
      }
      
      var lastWrapper2 = JCMS.form.Widget.getWidget(lastFocus);
      if (lastWrapper2){
        lastWrapper2.removeClassName('focus-widget');
      }
    }
    
    // Add new focus
    if (wrapper1 && !wrapper1.hasClassName('tab-page')){
      wrapper1.addClassName('focus-field');
    }
    
    if (wrapper2 && !wrapper2.hasClassName('tab-page')){
      wrapper2.addClassName('focus-widget');
    }
    
    // Fire event
    document.fire('jcms:focus',{ elmId: widget.identify() , lastId: JCMS.form.Widget._lastFocusId });
    JCMS.form.Widget._lastFocusId = widget.identify();
  },
  
  /**
   * -----------------------------------------------------------------------------
   * LANG TAB
   * -----------------------------------------------------------------------------
   */
  toggleLangForm: function(lang, elm){
    
    // Original Link
    var link     = $(CtxMenuManager.latestElement);
    
    // Find wrapper
    var wrapper = $(link).fastUp('FORM');
    
    return JCMS.form.Widget.toggleLangScope(lang, wrapper);
  },
  
  toggleLangScope: function(lang, scope){
    var scope = $(scope);
    if (!scope){  return false; }
    
    var elmId = scope ? '#'+scope.identify() : '';
    JCMS.util.StyleSheet.putRule('.js '+elmId+' .wdglang','display: none;');
    
    // Remove old rule
    if (scope._oldLang){
      JCMS.util.StyleSheet.removeRule('.js '+elmId+' .wdglang-'+scope._oldLang);
    }
    
    // Add new rule
    JCMS.util.StyleSheet.putRule('.js '+elmId+' .wdglang-'+lang,'display: block;');
    scope._oldLang = lang;
    
    // Update lang tags
    var img = $$('#ctxLangForm IMG.'+lang+'-flag').first();
    scope.select('A.ctxLangForm IMG.iso639flag').each(function(linkImg){
      var cloneImg = img.cloneNode(true);
      linkImg.parentNode.replaceChild(cloneImg,linkImg);
    });
    
    document.fire('tabpane:change', { tabPage: $(scope).identify() });
    
    return false;
  },
  
  /**
   * -----------------------------------------------------------------------------
   * UPLOAD FIELDS
   * -----------------------------------------------------------------------------
   */
  
  toggleUploadField: function(link){
    var link = $(link) || $(CtxMenuManager.latestElement);
    return JCMS.form.Widget._toggleUpload(link);
  },
  
  _toggleUpload: function(elm, showChooser){
    var wrapper = JCMS.form.Widget.getWrapper(elm);
    
    // Check upload context
    var upload  = wrapper.down('INPUT.formUploadfield');
    if (!upload || (upload.disabled && showChooser)){
      return; // Job already done
    }
    
    var lbl     = wrapper.down('INPUT.formChooserLabelfield');
    var chooser = wrapper.down('INPUT.formChooserfield');
    
    if (!upload.disabled){
      upload.disable(); upload.hide();
      lbl.show();       /*chooser.show();*/
      lbl.enable();     chooser.enable();
    } else {
      lbl.disable();    chooser.disable();
      lbl.hide();       chooser.hide();
      upload.show();    upload.enable();
    }
    return false;
  },
  
  
  /**
   * -----------------------------------------------------------------------------
   * WIDGET/FIELDS ACTIONS
   * -----------------------------------------------------------------------------
   */
   
   UI_EDITOR_COLORCHOOSER:        'F',
   UI_EDITOR_FILEPATH:            'P',
   UI_EDITOR_IMAGEPATH:           'I',
   UI_EDITOR_SIMPLEIMAGEPATH:     'I',
   UI_EDITOR_MEDIAPATH:           'M',
   UI_EDITOR_SIMPLEMEDIAPATH:     'M',
   UI_EDITOR_DATECHOOSER:         'V',
   
   UI_EDITOR_MEMBERCHOOSER:       'EHJY',
   UI_EDITOR_GROUPCHOOSER:        'EGY',
   UI_EDITOR_PUBLICATIONCHOOSER:  'EXMSCcY',
   UI_EDITOR_PUBLICATIONSCHOOSER: 'EXMSCcY',
   UI_EDITOR_CATEGORYCHOOSER:     'EZY',
   UI_EDITOR_CATEGORIESCHOOSER:   'EZY',
   UI_EDITOR_WORKSPACECHOOSER:    'EOY',
   UI_EDITOR_QUERYCHOOSER:        'QY',
   UI_EDITOR_SQLQUERY:            '',
   UI_EDITOR_DBRECORDCHOOSER:     '',
   
   CHOOSER_PATH: {
     'media': '/work/mediaBrowser.jsp?selectMode=true&medias=media&',
     'pub'  : '/work/pubChooser.jsp?',
     'ws'   : '/work/workspace/workspaceChooser.jsp?',
     'grp'  : '/admin/groupChooser.jsp?',
     'mbr'  : '/admin/memberChooser.jsp?',
     'query': '/work/queryChooser.jsp?',
     'cat'  : '/work/categoryChooser.jsp?',
     'file' : '/work/fileChooser.jsp?',
     'image': '/work/mediaBrowser.jsp?selectMode=true&medias=image&'
    },
   
   getWidget: function(elm){
     var elm = $(elm);
     return elm.fastUp(['DIV'],'widget',true,10);
   },
   
   getWrapper: function(elm){
     var elm = $(elm);
     return elm.fastUp(['DIV','LI'],null,true,10);
   },
   
   /**
    * Return params to provide to the RPC method
    * 
    * 
    * E => EditTag.getEditIcon()
    * R => clear()
    * T => remove()
    * A => add()
    * U => up()
    * D => down()
    * F => openColorChooser()
    * P => openFileChooser()
    * I => openImageChooser()
    * M => openMediaChooser()
    * y => Multilang
    * - => insert a separator
    * 
    * @param link 
    * @param menu
    * @return String the link classes or false/null to stop action
    * @see com.jalios.jcms.ajax.WidgetCtxMenu.java
    */
  fillCtxMenuHook: function(link,menu){
    try {
    
      var link = $(link);
      var items   = '';
      var wrapper = JCMS.form.Widget.getWrapper(link);
      var widget  = JCMS.form.Widget.getWidget(link);
      var wdglang = link.fastUp(['DIV'],'wdglang',true,10);
      
      if (!wrapper){ return; }
      
      var lang    = wdglang && wdglang.className.match(/wdglang-(\S+)/);
      if (lang){ lang = lang[1]; }
               
      // Handle Widget Kinds
      if (widget && widget.className){ 
        $w(widget.className).each(function(cn){
          if (JCMS.form.Widget[cn]){
            items += JCMS.form.Widget[cn];
          }
        });
      }
        
      // Handle Multivalued
      if (wrapper.tagName == 'LI'){ // It is a List !
        items = (wrapper.parentNode.tagName == 'OL') ? ('R'+items+'-ATUD-') : (items+'-AT-');
      } else {
        items = 'R' + items;
      }  
      
      // Handle Multilang
      if (widget.hasClassName('ml')){
        items += 'y';
      }
        
      // Handle Chooser's Hidden Input 
      var chooser = wrapper.down('INPUT.formChooserfield');
      if (!chooser){
        return items+"','"+lang+"','','";
      }
        
      var chooserId   = '';
      if (chooser.value){
        chooserId = chooser.value;
      }
      
      var chooserType = widget.className.match(/super_([\w\.]+)/);
      chooserType = (chooserType && chooserType.length > 1) ? chooserType[1] : '';
  
      return items+"','"+lang+"','"+chooserType+"','"+chooserId;
    
    } catch(ex){
      alert(ex || ex.message);
    }
  }, 
   
  /**
   * Clear Fields 
   */
  clear: function(link){
    var link    = $(link) || $(CtxMenuManager.latestElement);
    var wrapper = JCMS.form.Widget.getWrapper(link);
    
    wrapper.descendants().each(function(elm){
      
      if (elm.checked){ elm.checked = false; }
      else if (elm.selectedIndex){ elm.selectedIndex = 0; }
      else if (elm.clear){ elm.clear(); }
      
    });
     
    return false;
  },

  /**
   * Display Chooser Id
   */
  showChooserId: function(link){
    var link     = $(link) || $(CtxMenuManager.latestElement);
    var wrapper  = JCMS.form.Widget.getWrapper(link);
    var input    = wrapper.down('INPUT');
    var next     = input.next('INPUT');
    
    JCMS.form.Widget._toggleUpload(link, true);
    next.toggle();
    
    return false;
  },
  
  /**
   * Update the Durtion field of Duration Chooser
   */  
  updateDuration: function(elm,resolution){
    var wrapper = JCMS.form.Widget.getWrapper(elm);
    
    var wDuration = wrapper.down('INPUT');
    var wTime     = wDuration.next('INPUT');
    var wUnit     = wTime.next('SELECT');
    
    wTime.value = wTime.getValue().replace(/[^0-9]/, "");
    wDuration.value = wTime.getValue() * wUnit.getValue() / resolution;
  },
 
  /* 
   * CONTROL FIELDS
   */
   
  _clearChooser: function(event){
    var elm = $(event.memo.elmId);
    if(!elm || elm.value){ return; }
    
    var widget = JCMS.form.Widget.getWidget(elm);
    if(!widget.hasClassName('DataChooser')){ return; }
    
    JCMS.form.Widget.clear(elm);
  },
  
  _formatDate: function(event){
    var elm = $(event.memo.elmId);
    
    var wrapper  = JCMS.form.Widget.getWrapper(elm);
    if (!wrapper.hasClassName('UI_EDITOR_DATECHOOSER')){ return;  }
    
    var d = Date.parse(elm.value);
    if (!d){ return; }
    
    var widget   = JCMS.form.Widget.getWidget(elm);
    var showWeek = widget.hasClassName("showWeek");
    var dateOnly = !widget.hasClassName("showTime");
    var dformat  = I18N.glp(dateOnly ? 'datechooser.js.date-format' : 'datechooser.js.date-time-format');
    
    elm.value = d.toString(dformat);
  },
  
  _initKeypress: function(event){
    var elm = $(event.memo.elmId);
    
     // Is Input Text
    if(!elm || elm.type != 'text' || elm._keyField || elm.hasClassName('autocomplete')){ return; }
    
    // Is List
    var wrapper  = JCMS.form.Widget.getWrapper(elm);
    if (!wrapper || wrapper.tagName != 'LI'){
      return;
    }
    
    elm._keyField = true;
    Event.observe(elm,"keypress",function(event){
      var key = event.which || event.keyCode;
      if (!key || key != Event.KEY_RETURN){ return; }
      
      var input = Event.element(event); 
      if (!input.value){ return; }
      
      if (JCMS.form.Widget.add(input)){
        Event.stop(event);
      }
    });
    
    Event.observe(elm,"keydown",function(event){
      var key = event.which || event.keyCode;
      if (!key || key != Event.KEY_BACKSPACE){ return; }
      
      var input = Event.element(event); 
      if (input.value){ return; }
      
      if (JCMS.form.Widget.remove(input)){
        Event.stop(event);
      }
    });
    
  },


  /*
   * POPUP CALLBACK (When there is no hope)
   */
  _popupCallback: function(event){ 
    if (!event.memo){ return }
    
    var link   = $(event.memo.linkId);
    if (!JCMS.form.Widget.getWidget(link)){ // Are we in a widget ?  
      link =  $(CtxMenuManager.latestElement); // Should find a better way
      if (!JCMS.form.Widget.getWidget(link)){  
        return;
      }
    }
    
    var wrapper = JCMS.form.Widget.getWrapper(link);
    var input   = wrapper.down('INPUT'); 
    var args    = [input.identify()].concat($A(event.memo.args));
    JCMS.form.Widget._chooserCallback.apply(this,args); // call function with (id,arg1,arg2,...)
    
    // Toggle upload
    JCMS.form.Widget._toggleUpload(input,true);
  },
  _chooserCallback: function(inputId, id, title, media, url){
    var input = $(inputId);
    var next = input.next('INPUT');
    if (!id){ return; }
    if (next){
      next.value  = id;
      input.value = title;
    } else {
      input.value = url;
    }
  },
  
  /* 
   * OPEN CHOOSERS
   */
  
  openColorChooser: function(link){
    var link     = $(link) || $(CtxMenuManager.latestElement);
    var wrapper  = JCMS.form.Widget.getWrapper(link);
    var input    = wrapper.down('INPUT');
    var chooser  = JcmsJsContext.getContextPath()+'/work/colorChooser.jsp?color='+input.value.slice(1);
     
    var inputId  = input.identify(); 
    var callback = function(value){ 
      var input = $(inputId);
      input.value = value;
      input.style.backgroundColor = value;
    }
     
    return Popup.popupWindow(chooser, 'ColorChooser', 235, 220,'no','no','yes',false,false,callback);
  },
  
  openFileChooser:     function(){ JCMS.form.Widget._openChooser.apply(this,['file',700, 500,'yes'].concat($A(arguments))); return false;},
  openCatChooser:      function(){ JCMS.form.Widget._openChooser.apply(this,['cat',300,500,'yes'].concat($A(arguments)));   return false;},
  openQueryChooser:    function(){ JCMS.form.Widget._openChooser.apply(this,['query',900,500,'yes'].concat($A(arguments))); return false;},
  openWSChooser:       function(){ JCMS.form.Widget._openChooser.apply(this,['ws',900,500,'yes'].concat($A(arguments)));    return false;},
  openMbrChooser:      function(){ JCMS.form.Widget._openChooser.apply(this,['mbr',900,500,'yes'].concat($A(arguments)));   return false;},
  openGrpChooser:      function(){ JCMS.form.Widget._openChooser.apply(this,['grp',900,500,'yes'].concat($A(arguments)));   return false;},
  openPubChooser:      function(){ JCMS.form.Widget._openChooser.apply(this,['pub',900,500,'yes'].concat($A(arguments)));   return false;},
  openMediaChooser:    function(){ JCMS.form.Widget._openChooser.apply(this,['media',930,570,'no'].concat($A(arguments)));  return false;},
  openImageChooser:    function(){ JCMS.form.Widget._openChooser.apply(this,['image',930,570,'yes'].concat($A(arguments))); return false;},
  openImagePubChooser: function(){ JCMS.form.Widget._openChooser.apply(this,['image',930,570,'yes'].concat($A(arguments))); return false;},
  _openChooser:        function(media,w,h,resiz,link){
    var link      = $(link) || $(CtxMenuManager.latestElement);
    var wrapper   = JCMS.form.Widget.getWrapper(link);
    var widget    = JCMS.form.Widget.getWidget(link);
    var input     = wrapper.down('INPUT');
    var next      = input.next('INPUT');
    
    // Compute path
    var chsrpath  = JcmsJsContext.getContextPath() + JCMS.form.Widget.CHOOSER_PATH[media];
    if ('query'==media){ chsrpath += '&qs='+Popup.encode(next.value)+'&';     }
    if ('file'==media) { chsrpath += '&path='+Popup.encode(input.value)+'&';  }
    if ('cat'==media)  { 
      chsrpath += '&cidList='+Popup.encode(next.value)+'&';
      if (widget.hasClassName('UI_EDITOR_CATEGORIESCHOOSER')){
        chsrpath += 'multivalue=true&';
      }
    }
    if ('mbr'==media) {
      if (widget.className.indexOf('adminOnly') >= 0) { chsrpath += 'admin=true&';                }
      if (widget.className.indexOf('workerOnly') >= 0){ chsrpath += 'worker=true&';               }
      if (widget.className.indexOf('jstoreOnly') >= 0){ chsrpath += 'jstore=true&jcmsdb=false&';  }
    }
    
    // Detect super type chooser
    var superType = widget.className.match(/super_([\w\.]+)/);
    if (superType && superType.length > 1){
      chsrpath += "super=" + superType[1]+"&";
    }
    
    // Detect gids
    var superGrp = widget.className.match(/gids_[\w]+/g);
    if (superGrp && superGrp.length > 0){
      chsrpath   += superGrp.join('&').replace('gids_','gids=');
      chsrpath   += "&";
    }
    
    // Detect rootCat
    var rootCat = widget.className.match(/rootCat_([\w\.]+)/);
    if (rootCat && rootCat.length > 1){
      chsrpath += "rootCat=" + rootCat[1]+"&";
    }
    
    // Workspace Filter
    if (widget.className.indexOf('wsNoFilter') >= 0 
    ||  widget.className.indexOf('workspaceFilter_false') >= 0){ // Backward compatibility with chooserQS 
      chsrpath += 'workspaceFilter=false&'; // default is true
    }
    
    // Workspace
    var superWS = widget.className.match(/ws_([\w\.]+)/);
    if (superWS && superWS.length > 1){
      chsrpath += "ws=" + superWS[1]+"&";
    }
    
    // Setup callback
    var callback = JCMS.form.Widget._chooserCallback.bind(this,input.identify());
    
    // Toggle upload in case of Document
    JCMS.form.Widget._toggleUpload(link, true);
    
    JcmsLogger.warn('Chooser: ' + chsrpath);
    return Popup.popupWindow(chsrpath, 'Chooser', w, h,'no',resiz,resiz,false,false,callback);
  },
  
  /* Handle multiple fields*/
  openDocChooser:   function(link,isUpdate){
    var link     = $(link) || $(CtxMenuManager.latestElement);
    var widget   = JCMS.form.Widget.getWidget(link);
    
    if (!widget){
      var chooser  = JcmsJsContext.getContextPath()+'/work/docChooser.jsp?nbElt=1';
      var callback = function(fdIDs, fdTitles){ document.location = document.location; };
      return Popup.popupWindow(chooser, 'DocChooser', 640, 600,'no','yes','yes',false,false,callback);
    }

    var wrapper  = JCMS.form.Widget.getWrapper(link);
    var input    = wrapper.down('INPUT.formChooserfield');
    var nbElt    = wrapper.nextSiblings().size()+1;
    
    var chooser  = JcmsJsContext.getContextPath()+'/work/docChooser.jsp?nbElt='+nbElt;
    if (isUpdate){
      chooser = JcmsJsContext.getContextPath()+'/work/docChooser.jsp?nbElt=1&id='+input.value;
    }
    
    var wrapperId = wrapper.identify();
    var callback = function(fdIDs, fdTitles){
      var wrapper= $(wrapperId);
      var fields =  [wrapper].concat(wrapper.nextSiblings());
      fields.each(function(field, idx){
        if (idx >= fdIDs.size()){ return; }
        var lbl = field.down('INPUT.formChooserLabelfield');
        var val = field.down('INPUT.formChooserfield');
        lbl.value = fdTitles[idx];
        val.value = fdIDs[idx];
        
        // Toggle upload
        JCMS.form.Widget._toggleUpload(lbl,true);
      });
    } 
    return Popup.popupWindow(chooser, 'DocChooser', 640, 600,'no','yes','yes',false,false,callback);
  },
  
  
  _closeDateChooser: function(input){
    var calDiv   = $('calendar-container');
    if (!calDiv || !calDiv.visible()){  return false; }
    if (input && input.identify && calDiv.inputId != input.identify()){ return false; }
    
    calDiv.hide();
    return true;
  },
  
  openDateChooser: function(link){

    var link     = $(link) || $(CtxMenuManager.latestElement);
    var wrapper  = JCMS.form.Widget.getWrapper(link);
    var widget   = JCMS.form.Widget.getWidget(link);
    var input    = wrapper.down('INPUT');
    
    if (JCMS.form.Widget._closeDateChooser(input)){
      return;
    }
    
    var calDiv   = $('calendar-container');
    var showWeek = widget.className.indexOf("showWeek") >= 0;
    var dateOnly = widget.className.indexOf("showTime") < 0;
    var value    = input.value;
    var dformat  = I18N.glp(dateOnly ? 'datechooser.js.date-format' : 'datechooser.js.date-time-format');
    
    // Create Calendar 
    if (!calDiv){
      calDiv    = document.createElement('DIV');
      calDiv.id = 'calendar-container';
      document.body.appendChild(calDiv);
      calDiv.style.position = 'absolute';
      calDiv = $(calDiv);
    }
    
    // Create Calendar
    if (!window.calendar){
      // Setup callback
      var callback = function(cal){
        var sel    = cal.selection;
        var input  = $(cal.inputId);
        var calDiv = $('calendar-container');
        var date = Calendar.intToDate(
          sel.get(), cal.getHours(), cal.getMinutes()
        );
        input.value = date.toString(dformat);
        calDiv.hide();
      }
  
      // Setup Calendar    
      try {
        window.calendar = Calendar.setup({
          cont         : "calendar-container",  // ID of the parent element
          weekNumbers  : showWeek,
          showTime     : !dateOnly,
          onSelect     : callback
        });
      } catch(ex) { alert(ex.message || ex); }
    }
    
    // Set the date
    var d = Date.parse(input.value);
    window.calendar.inputId = input.identify();
    
    if (d){
      input.value = d.toString(dformat);
      window.calendar.setHours(d.getHours());
      window.calendar.setMinutes(d.getMinutes());
      window.calendar.selection.reset(d);
    }
    
    calDiv.inputId = input.identify();
    calDiv.clonePosition(link, { setWidth:false, setHeight:false, offsetTop: 24, offsetLeft: 24 });
    calDiv.show();
    
    return false;
  },

  /* 
   * MANIPULATE LIST (ML)
   */
  
  toggle: function(){ return JCMS.form.Widget._list.apply(this,['_toggle'].concat($A(arguments))); },
  add:    function(){ return JCMS.form.Widget._list.apply(this,['_add'].concat($A(arguments)));    },
  remove: function(){ return JCMS.form.Widget._list.apply(this,['_remove'].concat($A(arguments))); },
  up:     function(){ return JCMS.form.Widget._list.apply(this,['_up'].concat($A(arguments)));     },
  down:   function(){ return JCMS.form.Widget._list.apply(this,['_down'].concat($A(arguments)));   },
  reorder:function(){ return JCMS.form.Widget._list.apply(this,['_reorder'].concat($A(arguments)));},
   
  _add:  function(list, idx, current){ 
    
    var li1  = $(list.childElements()[idx]);
    if (!li1){ return; }
     
    // clone
    var li2  = $(li1.cloneNode(true));
    li2.id = '';
    li2.descendants().invoke('writeAttribute','id','');

    var next = li1.next();
    if (next){
      list.insertBefore(li2,next);
    } else {
      list.appendChild(li2);
    }
    
    // clear
    JCMS.form.Widget.clear(li2);
    
    // renumber
    JCMS.form.Widget._renumber(list,idx+1);
    
    // refresh
    document.fire('refresh:after' ,{ wrapper: li2.identify() });
    
    if (current){ // focus
      JCMS.form.Widget._focus.defer(li2);
    }
    
  },
   
  _remove: function(list, idx, current){
    var li = $(list.childElements()[idx]);
    if (li.siblings().length == 0){ return; }
    
    var prev  = li.previous() || $(li.parentNode).firstDescendant();
    li.remove();
    
    // renumber
    JCMS.form.Widget._renumber(list);
    
    if (current){ // focus defer because of IE !
      JCMS.form.Widget._focus.defer(prev);
    }
  },
 
  _focus: function(elm){
    if (!elm){ return }
    var elm = $(elm);
    var down = elm.down(['INPUT','TEXTAREA', 'SELECT']);
    if (down){ InputUtil.focus(down); }
  },
 
  _up: function(list, idx, current){
     
    var children = list.childElements();
    var li1 = children[idx];
    var li2 = idx-1 < 0 ? children[children.length-1] : children[idx-1];
   
    list.insertBefore(li1,li2);
    if (idx-1 < 0){
      list.insertBefore(li2,li1);
    }
    
    // renumber
    JCMS.form.Widget._renumber(list);
  },
   
  _down: function(list, idx, current){
    var children = list.childElements();
    var li1 = $(children[idx]);
    var li2 = idx+1 >= children.length ? children[0] : children[idx+1];
     
    if (idx+1 >= children.length){
      list.insertBefore(li1,li2);
    } else {
      list.insertBefore(li2,li1);
    }
    
    // renumber
    JCMS.form.Widget._renumber(list);
  },

  _toggle: function(list, idx, current){

    if (!list.hasClassName('wdg-tab')){ return; }
    
    JCMS.form.Widget._renumber(list,idx);
    
    if (current){
      var pane = $(list).next('OL.wdg-tabpane').down('LI',idx);
      document.fire('tabpane:change', { tabPage: $(pane).identify() });
    }
  },
  
  _reorder: function(list, idx, current, order){
    if (current){ return; } // Already done by DnD
    
    var list     = $(list);
    var children = list.childElements();
    var items    = $A();
     
    // Push children in order 
    order.each(function(idx){
      items.push(children[idx]);
    });

    // Remove all items
    list.childElements().each(function(elm,idx){
      list.removeChild(elm);
      if (items.indexOf(elm) < 0){
        items.push(elm);
      }
    });

    // Add back items 
    items.each(function(elm,idx){
      list.appendChild(elm);
    });
    
    // renumber
    JCMS.form.Widget._renumber(list);
  },
  
  _renumber: function(list, overrided){
    if (!list.hasClassName('wdg-tab')){ return; }
    
    var tabList  = $(list);
    var paneList = tabList.next('.wdg-tabpane');
    var toggle   = function(idx, show){
      var tab  = tabList.down('LI',idx)
      var pane = paneList.down('LI',idx);
      if (show){
        if (tab)  tab.addClassName('selected');
        if (pane) pane.show();
      } else {
        if (tab)  tab.removeClassName('selected');
        if (pane) pane.hide();
      }
    }
    
    var index = 0;
    tabList.childElements().each(function(li, idx){
      var ahref = li.down('A');
      if (ahref) { ahref.innerHTML = idx+1; }
      if (li.hasClassName('selected')){ index = idx; }
      toggle(idx, false); 
    });
    
    if (overrided != 'undefined'){
      index = overrided;
    }
    
    toggle(index, true);
  },
  
  
  
  _list: function(func, link, options){ 
    var link  = $(link) || $(CtxMenuManager.latestElement);
    
    var widget= JCMS.form.Widget.getWidget(link);
    if (!widget){ return false; }
    
    var li    = link.fastUp('LI',null,true,10);
    if (!li){ li =  $(link.parentNode).down('.wdg-list > LI:last-child'); } // link is sibling
    var ul    = $(li.parentNode);
    var idx   = ul.childElements().indexOf(li);
    
    // Always perform
    var next = ul.next('OL.wdg-list');
    if (next){ // Quick and Dirty
      JCMS.form.Widget[func](next, idx, true, options);
    }
    JCMS.form.Widget[func](ul, idx, true, options); 

    // Skip wysiwyg
    if (widget.hasClassName('UI_EDITOR_RICHTEXT')){ return true; }
     
    // Perform on sibling ML
    JCMS.form.Widget._listML(func, ul, idx, options);
    
    // Perform on widget group 
    JCMS.form.Widget._listGroup(func, widget, idx, options);
    
    return true;
  },
   
  _listML: function(func, list, idx, options){
    var lang  = list.fastUp('DIV','wdglang',true,4);
    if (!lang){ return; }
     
    lang.siblings().each(function(itLang){
      if(!itLang.hasClassName('wdglang')){ return; }
      
      itLang.select(['OL.wdg-list','UL.wdg-list']).each(function(list){ // order OL before Ul is very important !
        JCMS.form.Widget[func](list, idx, false, options);
      });
    });
  },
  
  _listGroup: function(func, widget, idx, options){
    if (!widget.hasClassName('wdg-group')){ return; }
    var group = widget.className.match(/wdggrp-(\S+)/);
    
    widget.fastUp('FORM',null,false,20).select('DIV.'+group[0]).each(function(wdg){
      if (wdg == widget){ return; }
      
      wdg.select(['OL.wdg-list','UL.wdg-list']).each(function(list){ // order OL before Ul is very important !
        JCMS.form.Widget[func](list, idx, false, options);
      });
    });
  }
});

// -----------------------------------------------------------------------------
//  EVENTS
// -----------------------------------------------------------------------------

  Event.observe(window,   'load' ,          JCMS.form.Widget.init );
  Event.observe(document, 'refresh:after' , JCMS.form.Widget._initBlurFocus);
  Event.observe(document, 'refresh:after' , JCMS.form.Widget._resetDragDrop);
  Event.observe(document, 'jcms:focus'    , JCMS.form.Widget._initResizer);
  Event.observe(document, 'jcms:focus'    , JCMS.form.Widget._initDragDrop);
  Event.observe(document, 'jcms:focus'    , JCMS.form.Widget._initKeypress);
  Event.observe(document, 'jcms:focus'    , JCMS.form.Widget._closeDateChooser);
  Event.observe(document, 'jcms:blur'     , JCMS.form.Widget._clearChooser);
  Event.observe(document, 'jcms:blur'     , JCMS.form.Widget._formatDate);
  Event.observe(document, 'popup:callback', JCMS.form.Widget._popupCallback);
  
  
// -----------------------------------------------------------------------------
//  INITIALISATION
// -----------------------------------------------------------------------------

function initUnloadMessage(){
  
  var func = function(event){
    if(event.keyCode == 116){  return; } // Skip F5 key
    window.onbeforeunload = function unloadMess() { return I18N.glp('warn.edit.contentlost'); } // Register unload message
    initKeyObs(false); // Unregister keypress listener
  }
  
  var initKeyObs = function(init){
    if (init){ Event.observe(document, 'keypress' , func); } 
    else    { Event.stopObserving(document, 'keypress' , func); }
  
    $A(window.frames).each(function(elm,idx){
      if (init){ Event.observe(elm.document, 'keypress' , func); } 
      else    { Event.stopObserving(elm.document, 'keypress' , func); }
    });
  };
  
  initKeyObs(true);
}


// -----------------------------------------------------------------------------
// TEST SQLQuery
// -----------------------------------------------------------------------------


function testSQLQuery(window, ctxPath, form, widget, pos, title){
  var sqlQuery   = form.elements[getFormElementPos(form,widget)+pos];
	var dataSource = form.elements[getFormElementPos(form,widget+"DataSource")+pos];
	var maxRows    = form.elements[getFormElementPos(form,widget+"MaxRows")+pos];
	
	var chooser    = ctxPath+"/work/checkSQLQuery.jsp?";
	    chooser   += "dataSource=" +escape(dataSource.value);
	    chooser   += "&maxRows="   +escape(maxRows.value);
	    chooser   += "&sqlQuery="  +escape(sqlQuery.value);
	
	// alert("pos: "+pos+"\ndataSource "+dataSource.value + "\nmaxRows " + maxRows.value + "\nsqlQuery "+sqlQuery.value);
	popupWindow(chooser, title, 400, 600,'no','yes','yes',false);   
}


// -----------------------------------------------------------------------------
// Wysiwyg
// -----------------------------------------------------------------------------

'JCMS.wysiwyg.TinyMceCB'.namespace({

  // --------------------------------------------------------------
  // onInit callback
  // All processed done here are made to make sure that we do not allow
  // form submit when content is not yet ready (which could submit partial on empty data).
    
  // Number of wysiwyg editor to be initialized for current page
  editorsNbr : 0,
  
  /**
   * Method invoked after each editor has been initialized properly (see onInit).
   */
  initInstanceCB : function (ed) {
    JCMS.wysiwyg.TinyMceCB.editorsNbr = JCMS.wysiwyg.TinyMceCB.editorsNbr - 1;
    JCMS.wysiwyg.TinyMceCB._checkWysiwygEditorInitialization(ed);
  },

  /**
   * This method should be called to check if all wysiwyg editors are completely ready.
   */
  _checkWysiwygEditorInitialization: function (ed) {
    if (ed) {
      JcmsLogger.debug('TinyMCE_JcmsPluginCB', '[', ed.id, '] [_checkWysiwyg] - editorsNbr:', JCMS.wysiwyg.TinyMceCB.editorsNbr);
    } else {
       JcmsLogger.debug('TinyMCE_JcmsPluginCB', '[_checkWysiwyg] - editorsNbr:', JCMS.wysiwyg.TinyMceCB.editorsNbr);
    }
    if (JCMS.wysiwyg.TinyMceCB.editorsNbr != 0) {
      return;
    }
    if (window.document.editForm && window.document.editForm.pageLoaded) {
      window.document.editForm.pageLoaded.value = 'true';
    }
  },
  
  /**
   * Count the number of editors on the page.
   * Used onload to initialized number of editors on page.
   */
  _countWysisygEditorOnPage : function() {
    JCMS.wysiwyg.TinyMceCB.editorsNbr += $$('TEXTAREA.formRichText').size();
    JCMS.wysiwyg.TinyMceCB._checkWysiwygEditorInitialization();
  }
});

Event.observe(window, 'load', JCMS.wysiwyg.TinyMceCB._countWysisygEditorOnPage);

// -----------------------------------------------------------------------------
// Fields 
// -----------------------------------------------------------------------------

function fillOpenerField(window, form, widget, pos, id, label){
  var widgetPos  = getFormElementPos(form,widget)+pos;
  form.elements[widgetPos].value   = id;
  form.elements[widgetPos-1].value = label;
  window.close();
}

function submitAddCount(window, form, widget, fullwidget, addCount, langCount, id){
  var elmCount = getFormElementCount(form, widget, id) / langCount;
  fullwidget.value = elmCount+addCount;
  simpleSubmitForm(window, form, "opRefresh", "Wait WYSIWYG");
}

// -----------------------------------------------------------------------------
// Form Element Access 
// -----------------------------------------------------------------------------

function getFormElementCount(form, name, id){
  // Get all elements
  var elms  = form.elements;
  var count = 0;
  
  // Count element
  for (var i = 0 ; i < elms.length ; i++){
    if (elms[i].name != name)
      continue;
      
    if (!id){
      count++;
      continue;
    }
    
    if ((elms[i].id == id) || (elms[i].id.indexOf(id) > -1)){ // very ugly
      count++;
    }
  }
  return count;
}

function getFormElementPos(form, name, id){
  // Get all elements
  var elms = form.elements;
 
  // Find out the (first) current element
  
  for (var i = 0 ; i < elms.length ; i++){
    if (elms[i].name != name) {
      continue;
    }      
    if (!id) {
      return i;
    }
    
    if ((elms[i].id == id) || (elms[i].id == id+'0') || (elms[i].id && elms[i].id.startsWith(id)) ){ // very ugly
      return i;
    }
  }
  return -1;
}

function getFormElementLastPos(form, name, first, id){
  // Get all elements
  var elms = form.elements;
 
  // Find out the (last) current element
  var last = -1;
  for (var i = 0 ; i < elms.length ; i++){

    if (elms[i].name != name){
      if (last > 0 && first)
        break;
      continue;
    }
      
    if (!id){
      last = i;
      continue;
    }
      
    if (elms[i].id.indexOf(id) > -1){
      last = i;
      continue;
    }
    
    if (last > 0 && first)
      break;
  }
  return last;
}

// -----------------------------------------------------------------------------
// Button 
// -----------------------------------------------------------------------------

function toggleSingleSubmitButton(evt, form, on){

	// check "this" is a form, otherwise, use given form
	if (this.elements) {
	  form = this;
	}

	// Enable/Disable all formButton
	var elements = $(form.elements);
	for (var i = 0 ; i < elements.length ; i++){
    var elm = $(elements[i]);

	  if (!on){
		  if (!elm.hasClassName("formButton")) { continue; }
		  elm.addClassName("disabledButton");
		  elm.oldclick = elm.onclick;
		  elm.onclick  = function(event){ return false; }
	  } else {
	    if (!elm.hasClassName("disabledButton")) { continue;  }
	    elm.removeClassName("disabledButton");
		  elm.onclick  = elm.oldclick;
		  elm.oldclick = null;
	  }
  }
  
  // Register/Unregister myself
  if (!on){
	  form.oldsubmit = form.onsubmit;
	  form.onsubmit  =  function(event){ return false; }
    window.onbeforeunload = null;	  // disable the warning msg put in doEditPubFooter.jsp
  }
  else{
	  form.onsubmit  =  form.oldsubmit;
	  form.oldsubmit = null;
  }
}

function setupSingleSubmitButton(off){
  
  // Register function
  try{
  var forms = document.forms;
  for (var i = 0 ; i < forms.length ; i++){
    var form = $(forms[i]);
    
    if (form.hasClassName("noSingleSubmitButton"))
      continue;
      
    if (off){
      toggleSingleSubmitButton(null, forms[i], true);
      continue;
    }
    
    if (form.ssb){
      continue;
    }
    form.ssb = true;
    
    var onsubmit = form.onsubmit;
    if (typeof onsubmit == 'function') {
      form.onsubmit = function(evt){
        toggleSingleSubmitButton(evt, this);
        return onsubmit(evt, this);
      };
    }
    else{
      form.onsubmit = toggleSingleSubmitButton;
    }
  }
  } catch(ex){ alert(ex); }
}


// -----------------------------------------------------------------------------
// Form 
// -----------------------------------------------------------------------------

/**
 * form should be like: window.document.editForm
 */ 
function simpleSubmitForm(window, fullform, action, warn, anchorValue, actionValue) {
  
  if(fullform.pageLoaded && fullform.pageLoaded.value=='false') {
    alert(warn);
    return;
  }

  for (var i = 0; i < fullform.elements.length; i++) {
    if (fullform.elements[i].jcmsSubmitCallBack != null) {
      fullform.elements[i].jcmsSubmitCallBack(window, fullform, action, warn, anchorValue);
    }
  }

  if (anchorValue){
  	fullform.anchor.value = anchorValue;
  }
  
  if (action && fullform.action){
    fullform.action.name  = action;
    if (actionValue)
      fullform.action.value = actionValue;
  }
  
  if (fullform.onsubmit)
    fullform.onsubmit();
  fullform.submit();
}

function confirmSubmitForm(window, fullform, action, msg, warn, anchorValue, actionValue) {
  if (top.confirm(msg)) {
    simpleSubmitForm(window, fullform, action, warn, anchorValue, actionValue);
  }
}
function confirmSubmitFormLightBox(window, fullform, action, msg, warn, anchorValue, actionValue) {
  JCMS.window.Modal.confirm(msg, function(ok) {
    if (ok) {
      simpleSubmitForm(window, fullform, action, warn, anchorValue, actionValue);
    }
  });
}

function getFormName(document, form){
  if (document.all){
    if (form.attributes){
      if (form.attributes.getNamedItem){
      	return form.attributes.getNamedItem("NAME").value;
      }
      else{
      	if (form.attributes["name"])
      	  return form.attributes["name"];
      	else if (form.attributes["NAME"])
      	  return form.attributes["NAME"];
      	else
      	  return 'editForm';
      }
    }
    else{
    	return 'editForm';
    }
  }
  else{
    return form.getAttribute("NAME");
  }
}

// -----------------------------------------------------------------------------
// EditPubFooter: DEPRECATED Should be removed or replaced
// -----------------------------------------------------------------------------
	

	function submitForm(action, anchor, actionvalue) {  
	  simpleSubmitForm(window, window.document.editForm, action,'Error',anchor, actionvalue);
	}
	function confirmSubmit(msg, action, anchor, actionvalue) {
    confirmSubmitForm(window, window.document.editForm, action, msg, anchor, actionvalue)
	}
	function submitAction(action, value) {
	  simpleSubmitForm(window, window.document.editForm, action,'Error',null, value);
	}
	
	/* This function are no longer used in JCMS 5.5
		function removeField(element, anchor) {
		  element.value = "__remove__";
		  submitForm("opRefresh", anchor);
		}
		function removeSelectedIndex(element, anchor) {
		  element.options[element.selectedIndex].value = "__remove__";
		  submitForm("opRefresh", anchor);
		}
		function clearSelectedIndex(element) {
		  element.selectedIndex=0;
		}
		function validateListItem(action, list, pos) {
		  window.document.editForm.opItem.name = action;
		  window.document.editForm.opItem.value = list;
		  window.document.editForm.itemPos.value = pos;
		  submitForm("opRefresh", list);
		}
	*/

