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


'JCMS.form.Widget'.namespace({
  init: function(){
    var t0 = new Date().getTime();
    
    setupSingleSubmitButton();
    
    Util.observeFocusClass('formTextfield', JCMS.form.Widget._handleBlurFocus);
    Util.observeFocusClass('formTextarea', JCMS.form.Widget._handleBlurFocus);
    
    var t1 = new Date().getTime();
    JcmsLogger.info('Widget', 'Init Widgets', ' in '+(t1-t0)+' ms');
  },

  /**
   * -----------------------------------------------------------------------------
   *  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));
    });
  },
  
  _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; }
    
    var list   = widget.fastUp(['DIV','OL','UL'],null,true,10);
    
    // 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; }
        JcmsLogger.debug('Widget','_initDragDrop','Sotable.destroy',drag.identify());
        Sortable.destroy(drag);
        drag.removeClassName("dragdrop")
      }
    }
    
    if (!list || list.hasClassName("dragdrop") || list.tagName == "DIV" || list.hasClassName('wdg-tabpane')){ return; }
    
    list.addClassName("dragdrop");
    list._draggable = list.childElements().invoke('identify'); // TODO: use fastEach
    
    // Known bug: Sortable.create stop <input type='file' /> popup
    JcmsLogger.debug('Widget','_initDragDrop','Sotable.create',list.identify());
    Sortable.create(list.identify(), { tag: 'LI',
                                       overlap: 'vertical',
                                       constraint: 'vertical',
                                       ghosting: false,
                                       onUpdate: JCMS.form.Widget._dndField,
                                       handles: list.select('IMG.grip'),
                                       tree: false,
                                       treeTag: list.tagName
    });
  },

  _initDragDropTab: function(event){
    //if (JcmsJsContext.isIE && !JcmsJsContext.isIE8){ return; }
 
    var widget = $(event.memo.elmId); 
    var last   = $(event.memo.lastId);
    
    // Current
    if (!widget){ return; }
    
    var wrapper = JCMS.form.Widget.getWidget(widget);
    
    if (!wrapper){ return; }
    var wdgtab  = wrapper.fastChild('UL','wdg-tab-grp');
    
    // Removing last
    if (last){
      var lastw   = JCMS.form.Widget.getWidget(last);
      var lasttab = lastw.fastChild('UL','wdg-tab-grp');
      if (lasttab && lasttab.hasClassName("dragdrop")){
        if (lasttab == wdgtab){ return; }
        JcmsLogger.debug('Widget','_initDragDropTab','Sotable.destroy',lasttab.identify());
        Sortable.destroy(lasttab);
        lasttab.removeClassName("dragdrop");
      }
    }
    
    if (!wdgtab || wdgtab.hasClassName('dragdrop')){ return; }
    
    wdgtab.addClassName('dragdrop');
    wdgtab._draggable = wdgtab.childElements().invoke('identify'); // TODO: use fastEach
    
    // Known bug: Sortable.create stop <input type='file' /> popup
    JcmsLogger.debug('Widget','_initDragDropTab','Sotable.create',wdgtab.identify());
    Sortable.create(wdgtab.identify(), { tag:        'LI',
                                         overlap:    'horizontal',
                                         constraint: 'horizontal',
                                         ghosting:   false,
                                         onUpdate:    JCMS.form.Widget._dndField,
                                         tree:       false,
                                         treeTag:    'UL'
    });
  },

  _dndField: function(container){
    // Retrieve order
    var old   = container._draggable;
    var order = container.childElements().collect(function(elm){ // FIXME: Use fastEach
      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
    container._skip = true;
    JCMS.form.Widget.reorder(container.down('LI'),order);
    container._skip = false;
  },
  
  _resetDragDrop: function(event){  
    var widget = $(event.memo.wrapper);
    if (!widget){ return; }
    
    if (widget.hasClassName('dragdrop')){
      // FIXME: Sortable.destroy(widget);
      list.removeClassName("dragdrop");
      return;
    }
    
    var list = widget.fastUp(['DIV','OL','UL'],null,true,10);
    if (list.hasClassName('dragdrop')){
      // FIXME: Sortable.destroy(list);
      list.removeClassName("dragdrop");
    }
  },

  /**
   * -----------------------------------------------------------------------------
   * BLUR / FOCUS
   * -----------------------------------------------------------------------------
   */
   
  _lastFocusId: false,
  
  _handleBlurFocus : function(event, elm, className, eventName){
     var elm = $(elm);
     if (eventName === 'focus:in'){
       JCMS.form.Widget.fireFocus(event, elm, className);
     } 
     else if (eventName === 'focus:out') {
      JCMS.form.Widget.fireBlur(event, elm, className);
     }
   },

  fireBlur: function(event, input){
    var widget = JCMS.form.Widget.getWidget(input);
    if (!widget || widget.hasClassName("disabled")){ return; }
    
    /* Will blur on document click 
      var lastId = JCMS.form.Widget._lastFocusId;
      JCMS.form.Widget._focusClasses(false, $(lastId));
    */
    
    document.fire('jcms:blur',{ elmId: input.identify() });
  },
  
  fireFocus: function(event, input){
    var lastId = JCMS.form.Widget._lastFocusId;
    
    // Toggle Focus/Class
    if (!JCMS.form.Widget._focusClasses(input, $(lastId))){
      return;
    }
    
    // Fire event
    document.fire('jcms:focus',{ elmId: input.identify() , lastId: lastId });
  },
  
  _focusClasses: function(widget, lastFocus){
  
    // Do not fire twice on the same element
    if (widget == lastFocus){ return false; }
    
    var wrapper1 = JCMS.form.Widget.getWrapper(widget);
    var wrapper2 = JCMS.form.Widget.getWidget(widget);
    if (wrapper2 && wrapper2.hasClassName("disabled")){
      return false;
    }
    
    // Remove last focus
    if (lastFocus){
      JCMS.form.Widget._lastFocusId = false;
      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');
      }
    }
    
    if (!widget) {
      return false;
    }
    
    JCMS.form.Widget._lastFocusId = widget.identify();
    
    // Add new focus
    if (wrapper1 && !wrapper1.hasClassName('tab-page')){
      wrapper1.addClassName('focus-field');
    }
    
    if (wrapper2 && !wrapper2.hasClassName('tab-page')){
      wrapper2.addClassName('focus-widget');
    }
    
    return true;
  },
  
  /**
   * -----------------------------------------------------------------------------
   * 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('tabwdg:change', { tabPage: $(scope).identify() });  // Fire Event Tab Widget
    
    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){
     if (!elm){ return; }
     var elm = $(elm);
     return elm.fastUp(['DIV','SPAN'],'widget',true,10);
   },
   
   getWrapper: function(elm){
     if (!elm){ return; }
     var elm = $(elm);
     return elm.fastUp(['DIV','SPAN','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 cid
    var superCid = widget.className.match(/cid_[\w]+/g);
    if (superCid && superCid.length > 0){
      chsrpath   += superCid.join('&').replace('cid_','cid=');
      chsrpath   += "&";
    }
    
    // Detect rootCat
    var rootCat = widget.className.match(/rootCat_([\w\.]+)/);
    if (rootCat && rootCat.length > 1){
      chsrpath += "rootCat=" + rootCat[1]+"&";
    }
    
    // Detect pStatus
    var pstatus = widget.className.match(/pstatus_(-?\d+)/);
    if (pstatus && pstatus.length > 1){
      chsrpath += "pstatus=" + pstatus[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+'&hideUnzip=true';
    if (isUpdate){
      chooser = JcmsJsContext.getContextPath()+'/work/docChooser.jsp?nbElt=1&hideUnzip=true&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; }
    
    /* Blur before copy
    if (current){ // blur
      JCMS.form.Widget._blur.defer(li1);
    }*/
     
    // clone
    var li2  = $(li1.cloneNode(true));
    Util.cleanDOMElements(li2,true,'generated'); 
    li2.removeAttribute('id');
    Element.removeClassName(li2,'showPrev'); /* showPrev for wysiwyg popup */

    var next = li1.fastNext('LI');
    if (next){
      list.insertBefore(li2,next);
    } else {
      list.appendChild(li2);
    }
    
    // tweeks
    // Should remove generated elements with a given classname
    
    // clear
    JCMS.form.Widget.clear(li2);
    
    // renumber
    JCMS.form.Widget._renumber(list,true,idx+1);
    JCMS.form.Widget._retoggle(list,idx+1,current);
    
    // refresh
    if (list.className.indexOf('wdg-tab-grp') < 0){ // Do not fire for tab
      document.fire('refresh:widget' ,{ 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 pos   = idx-1;
    var prev  = li.fastPrevious('LI');
    if (!prev){
      prev = $(li.parentNode).firstDescendant();
      pos = 0
    }

    li.remove();
    
    // renumber
    JCMS.form.Widget._renumber(list,true,pos);
    JCMS.form.Widget._retoggle(list,pos,false);
    
    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']); // TODO: fastChild() ?
    if (down){ InputUtil.focus(down); }
  },
  
  _blur: function(elm){
    if (!elm){ return }
    var elm = $(elm);
    var down = elm.down(['INPUT','TEXTAREA', 'SELECT']); // TODO: fastChild() ?
    if (down){ InputUtil.blur(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,true);
  },
   
  _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,true);
  },

  _toggle: function(list, idx, current){
    
    JCMS.form.Widget._renumber(list,false,idx);
    JCMS.form.Widget._retoggle(list,idx,current);
  },
  
  _reorder: function(list, idx, current, order){ 
  
    if (list._skip){
      JCMS.form.Widget._renumber(list,true);
      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){
      if (!elm){ return; } // Case (+)
      list.appendChild(elm);
    });
    
    // renumber
    JCMS.form.Widget._renumber(list,true);
  },
  
  _renumber: function(list, number, overrided){
    if (!list.hasClassName('wdg-tab-grp')){ return; }
    var tabList = $(list);
    
    var index = 0;
    var idx   = 0;
    for (var li = tabList.firstChild; li; li = li.nextSibling){
      if (li.nodeType != 1){ continue; } 
      var li = $(li);
      if (number){
        var ahref = li.fastChild('A');
        if (ahref && ahref.innerHTML*1 != idx+1) { ahref.innerHTML = idx+1; }
      }
      
      if (li.className.indexOf('selected') >= 0){ 
        index = idx;
        li.removeClassName('selected'); 
      }
      
      idx++;
    }
    
    if (overrided != undefined){
      index = overrided;
    }
    
    var tab  = tabList.fastChild('LI',false,index);
    if (tab)  tab.addClassName('selected');
    
    return index;
  },
  
  _retoggle: function(list, overrided, current){
    if (!list.hasClassName('wdg-tabpane')){ return; }
    var paneList = $(list);
    
    var idx = 0;
    for (var li = paneList.firstChild; li; li = li.nextSibling){
      if (li.nodeType != 1){ continue; }
      
      // Hide all
      $(li).hide();
      
      idx++;
    }
  
    if (overrided != 'undefined'){
      index = overrided;
    }
    
    // Show index
    var pane = paneList.fastChild('LI',false,index);
    if (!pane) { return;}
    
    pane.show();
    
    if (pane.fastVisible()) {
      document.fire('tabwdg:change', { tabPage: $(pane).identify() });  // Fire Event Tab Widget
    }
  },

  _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);
    
    // Skip wysiwyg
    // if (widget.hasClassName('UI_EDITOR_RICHTEXT')){ return true; }
    
    // Perform on widget Group and ML 
    if (widget.hasClassName('wdg-group')){
      JCMS.form.Widget._listGroup(func, widget, idx, options);
    }
    // Perform on widget ML
    else if (widget.hasClassName('ml')){
      JCMS.form.Widget._listML(func, ul, idx, options);
    }
    // Perform on widget
    else {
      // Always perform
      var next = ul.fastNext('OL','wdg-list'); // Chercher next et down dans la bonne langue
      if (next){ // Quick and Dirty
        JCMS.form.Widget[func](next, idx, true, options);
      }
      JCMS.form.Widget[func](ul, idx, true, options);
    }
    
    return true;
  },

  _listML: function(func, list, idx, options){
    
    if (list.tagName == 'UL'){
      var lang  = list.fastNext('DIV','wdglang',true,4);
      if (!lang){ return; }
      JCMS.form.Widget[func]($(list), idx, false, options); // Do it on UL
      list = lang;
    }
  
    var lang  = list.fastUp('DIV','wdglang',true,4);
    if (!lang){ return; }
    
    for ( ; lang ; lang = lang.nextSibling){
      if (lang.nodeType != 1){ continue; }
      if(!lang.className.indexOf('wdglang') < 0){ continue; }
      
      var ol = $(lang.firstChild);
      if (!ol){ continue; }
      JCMS.form.Widget[func](ol, idx, ol.fastVisible(), options);
    }
  },
  
  _listGroup: function(func, widget, idx, options){
    var group  = widget.className.match(/wdggrp-(\S+)/);
    var group0 = 'DIV.'+group[0];
    var form   = widget.fastUp('FORM',null,false,20);
    
    // Caching elements
    var cache  = form.retrieve(group0);
    if (!cache){
      cache = $A([]); form.store(group0,cache);
      form.select(group0).each(function(wdg){
        var list = wdg.select(['UL.wdg-list','OL.wdg-list']); // Order ! for renumber
        cache.addAll(list);
      });
    }
    
    // Iterate on cached list
    cache.each(function(list){
      var current = list.fastVisible() && JCMS.form.Widget.getWidget(list) == widget;
      JCMS.form.Widget[func](list, idx, current, options);
    });
  }
});

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

  Event.observe(window,   'load' ,          function(){ JCMS.form.Widget.init.defer(); });
  Event.observe(document, 'refresh:widget', 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._initDragDropTab); 
  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() {
    var t0 = new Date().getTime();
    
    JCMS.wysiwyg.TinyMceCB.editorsNbr += $$('TEXTAREA.formRichText').size();
    JCMS.wysiwyg.TinyMceCB._checkWysiwygEditorInitialization();
    
    var t1 = new Date().getTime();
    JcmsLogger.info('Widget', 'Init WysisygEditor Count', ' in '+(t1-t0)+' ms');
  }
});

Event.observe(window, 'load', function(){ 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 restrictToNumerics(input) {
   var re = new RegExp("[^0-9]");
   var value = input.value;
   var cleaned = value.replace(re, "");
   input.value = cleaned;
  }

  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);
    }
  */


