var widget = {};

widget.colorPickers = {};

widget.ColorPicker = Class.create();

widget.ColorPicker.prototype = {
    /**
     * Constructor
     *
     * @param name - id of the color picker
     * @param initialColor - initial color hex string ("#000000")
     * @param alertMsg - localized error msg string ("Error: A valid color value must be specified")
     * @param previewIdStr - optional id string of the color preview DIV container user can specify
     */
    initialize: function(name, initialColor, alertMsg, previewIdStr, previewBackgroundIdStr)
    {
        this.theColorPickerName = name;
        this.theMenu = $(name);
        this.alertMsg = alertMsg;        
        this.userPreviewContainer = $(previewIdStr); // may be undefined        
        this.userPreviewBackgroundContainer = $(previewBackgroundIdStr); // may be undefined    
        if (typeof this.userPreviewContainer == "undefined") {
          this.userPreviewContainer = null;
        } 
        if (typeof this.userPreviewBackgroundContainer == "undefined") {
          this.userPreviewBackgroundContainer = null;
        }     
        this.colorListParent = $(name + '_colorlist_parent');
        this.colorList = $(name + '_colorlist');
        
        widget.ColorPicker.registerColorPicker( this );
        
        this.ie = document.all && navigator.userAgent.indexOf("Opera") == -1;
        this.color_hidden_input = $(name + "_title_color_input");
        this.color_hidden_input.value = initialColor;
        this.color_hidden_input._defaultValue = initialColor;
        this.anch_link = $(name + "_link");
        this.color_link = $(name + "_img");
        this.color_name_label = $(name + "_color_name_label");
        this.title_color_input = $(name + "_title_color");
        this.setDisplay(initialColor, this.getColorByValue(initialColor,false));
        this.color_name_label.innerHTML = this.getColorByValue(initialColor,true);
        this.color_link.setStyle({background:initialColor});
        this.updateUserPreviewContainerColor(initialColor);
        if ( this.anch_link )
        {
            Event.observe(this.anch_link, "click", this.onOpen.bindAsEventListener(this));
        }
        Event.observe(document.body, "click", this.closeColorPickers.bindAsEventListener(this));
        Event.observe( this.theMenu , 'keydown', this.onKeyPress.bindAsEventListener( this ) );
        Event.observe( this.colorList, 'click', this.setColorFromSwatch.bindAsEventListener(this));
        Event.observe( this.theColorPickerName + '_previewColorLink', 'click', this.previewListener.bindAsEventListener(this));
        Event.observe( this.theColorPickerName + '_cancelButton', 'click', this.onClose.bindAsEventListener(this));
        Event.observe( this.theColorPickerName + '_submitButton', 'click', this.onApply.bindAsEventListener(this));

        this.skip_link = $(name + "_skip_link");
        if ( this.skip_link )
        {
          Event.observe(this.skip_link, "click", this.onSkipLinkClick.bindAsEventListener(this));
        }

        // relocate color picker popup div to the bottom of the doc b/c of css display issues
        Element.remove(this.colorList);
        Element.remove( this.theMenu );
        document.body.appendChild( this.theMenu );
        
        widget.colorPickers[ this.theColorPickerName ] = this;
    },

    onSkipLinkClick:function(event)
    {
	   $(this.theColorPickerName + '_submitButton').focus();
    },

    onKeyPress: function( event )
    {
      var key = event.keyCode || event.which;
      if ( key == Event.KEY_ESC )
      {
        this.onClose(event);
      }
    },  

    closeColorPickers:function(event)
    {
      var element = Event.element( event );
      widget.ColorPicker.colorPickers.each(function(cp)
       {
         if ( cp != this && !element.descendantOf( cp.theMenu ) )
         {
           cp.close();
         }
       }.bind(this));
    },    
    setOnChangeHandler: function( handler )
    {
    	this.onChangeHandler = handler;
    },    
    setDefaultColor: function( colorValue )
    {
        this.color_hidden_input.value = colorValue;
        this.color_hidden_input._defaultValue = colorValue;
        this.color_link.setStyle({backgroundColor: colorValue});
        this.setDisplay(colorValue, this.getColorByValue(colorValue,false));
        this.color_name_label.innerHTML = this.getColorByValue(colorValue,true);
    },    
    setColor:function(colorValue)
    {
        widget.ShowUnsavedChanges.changeHiddenValue( this.color_hidden_input, colorValue );
        this.color_link.setStyle({backgroundColor: colorValue});
        this.setDisplay(colorValue, this.getColorByValue(colorValue,false));
        this.color_name_label.innerHTML = this.getColorByValue(colorValue,true);
		if ( this.onChangeHandler )
		{
			this.onChangeHandler();
		}
    },
    
    getColorByValue:function(colorValue,onlyColorName)
    {
        var newValue = this.theColorPickerName + '_' + colorValue.substring(1, colorValue.length);
        e = $(newValue);
        var text = "";
        if (e != null)
        {
            text = this.getDisplayColorInfo(e.innerHTML,onlyColorName);
        }
        return text;
    },
    
    
    onOpen:function(event)
    {
      this.colorListParent.appendChild( this.colorList );
      var offset = Position.cumulativeOffset( this.anch_link );
      this.theMenu.setStyle({display: "block", position: "absolute"});
      var width = this.theMenu.getWidth();
      var bodyWidth = $(document.body).getWidth();
      if ( page.util.isRTL() )
      {
        offset[0] = offset[0] + this.anch_link.getWidth() - width;
      }
      if ( offset[0] + width > bodyWidth )
      {
        offset[0] = offset[0] - width + 30;
      }
      var ypos = offset[1] + this.anch_link.getHeight();
      this.theMenu.setStyle({ left: offset[0] + "px", top: ypos + "px"});
      //this.theMenu.scrollIntoView(true);
      this.title_color_input.focus();
      this.closeColorPickers(event);
      Event.stop(event);
    },

    /**
     * Hides the color picker.
     */
    onClose: function()
    {
      this.close();
      this.anch_link.focus();
    },

    close: function()
    {
      Element.remove(this.colorList);
      this.theMenu.setStyle({display: "none"});
    },

    /**
     * Sets the preview color and text to the color selected by the user in the palette
     */
    setColorFromSwatch:function(event)
    {
        var text = Event.element(event).childNodes[0].nodeValue;
        if (text)
        {
          this.setDisplay(text.substring(0, 7), this.getDisplayColorInfo(text,false));
        }
        Event.stop( event );
    },

    getDisplayColorInfo:function(nodeValue,onlyColorName)
    {
        var hex, hexname;
        if (nodeValue == null || nodeValue == "") return "";
        hex = nodeValue.substring(0, 7);
        hexname = nodeValue.substring(8);
        colorName = hexname + ' (' + hex + ')';
        if(onlyColorName)
        {
           colorName = hexname;
        }
        return colorName;
    },
    
    /**
     * Handles the Preview functionality on the swatch. If an inappropriate color is choosen, a msg is displayed to the user.
     * Else updates the color preview with the manually entered color.
     */
    previewListener:function(event)
    {
        if (this.isValidColor(this.title_color_input.value) == false)
        {
            alert(  this.alertMsg );
            return;
        }
        if (this.title_color_input.value.length != 6)
        {
            return;
        }
        var prevCol = '#' + this.title_color_input.value
        this.setDisplay(prevCol, this.getColorByValue(prevCol,false));
        Event.stop(event);
    },

    /**
     * Updates the color preview panel in the picker pop up
     */
    setDisplay:function(col, text)
    {
        $(this.theColorPickerName+'_swatchpreview').setStyle({backgroundColor:col});
        this.title_color_input.value = (col.startsWith('#')) ? col.substr(1) : col;
        $(this.theColorPickerName+'_title_color_name').innerHTML = text;
        $(this.theColorPickerName+'_color_text').setStyle({color:col});     
    },

    /**
     * Checks for a valid color value.
     */
    isValidColor:function(color_value)
    {
        if (! /^[0-9A-Fa-f]{6}/.test(color_value))
        {
            return false;
        }
        else
        {
            return true;
        }
    },

    /**
     * Manages the functionality for the Apply button the swatch.
     */
    onApply:function(event)
    {
      var color = this.title_color_input.value;
      if (this.isValidColor(color) == false)
      {
        return;
      }        
      color = '#' + color;
      this.color_link.setStyle({background:color});
      widget.ShowUnsavedChanges.changeHiddenValue( this.color_hidden_input, color );      
      this.color_name_label.innerHTML = this.getColorByValue(color,true);
      this.updateUserPreviewContainerColor(color);
      this.onClose();
	if ( this.onChangeHandler )
	{
	  this.onChangeHandler();
	}
      Event.stop(event);
    },

    /**
     * If the user specified preview container element exists,
     * update its color style to the color given.  
     *
     * @param color - color hex string
     */
    updateUserPreviewContainerColor:function( color )
    {
      if( this.userPreviewContainer )
      {
        this.userPreviewContainer.style.color = color;
      } 
      else if( this.userPreviewBackgroundContainer )
      {
        this.userPreviewBackgroundContainer.style.background = color;
      }        
    }

}; //end widget.ColorPicker.prototype

widget.ColorPicker.colorPickers = [];
widget.ColorPicker.colorPickerMap = {}


widget.ColorPicker.registerColorPicker = function(cp)
{
    widget.ColorPicker.colorPickers.push(cp);
    widget.ColorPicker.colorPickerMap[cp.theColorPickerName] = cp;
};

widget.ColorPicker.closeAllColorPickers = function()
{
    widget.ColorPicker.colorPickers.each(function(cp)
    {
        cp.theMenu.setStyle({display: "none"});
    });
};

widget.MultiSelect = Class.create()

widget.MultiSelect.multiselectBoxes = [];

// ---------------- "static" methods

widget.MultiSelect.registerMultiSelect = function(ms)
{
    widget.MultiSelect.multiselectBoxes.push(ms);
};

widget.MultiSelect.unRegisterMultiSelect = function(ms)
{
    widget.MultiSelect.multiselectBoxes.remove(ms);
};


widget.MultiSelect.prototype =
{
    initialize: function(multiSelectDiv, formName)
    {
        this.multiSelectDiv = $(multiSelectDiv);
		this.formName = formName;
		      
        if( this.multiSelectDiv != null )
        {
          this.leftClickListeners = new Array();
          this.rightClickListeners = new Array();
          var divs = this.multiSelectDiv.getElementsByTagName('div');
          var leftDiv = $(divs[0]);
          var buttonDiv = $(divs[1]);
          var rightDiv = $(divs[2]);

          var inputs = this.multiSelectDiv.getElementsByTagName('input')
          this.leftValues = $(inputs[0]);
          this.rightValues = $(inputs[1]);
          var leftSelects = leftDiv.getElementsByTagName('select');
          var rightSelects = rightDiv.getElementsByTagName('select');
          this.leftSelectBox = $(leftSelects[0]);
          this.rightSelectBox = $(rightSelects[0]);

          var buttons = buttonDiv.getElementsByTagName('button');
          var moveRightButton = $(buttons[0]);
          var moveLeftButton = $(buttons[1]);
          var leftInputs = leftDiv.getElementsByTagName('input');
          var leftInvertSelectionButton = $(leftInputs[0]);
          var leftSelectAllButton = $(leftInputs[1]);
          var rightInputs = rightDiv.getElementsByTagName('input');
          var rightInvertSelectionButton = $(rightInputs[0]);
          var rightSelectAllButton = $(rightInputs[1]);
          widget.MultiSelect.registerMultiSelect( this );
          Event.observe(moveLeftButton, "click", this.onMoveLeftClick.bindAsEventListener(this));
          Event.observe(moveRightButton, "click", this.onMoveRightClick.bindAsEventListener(this));
          Event.observe(leftInvertSelectionButton, "click", this.onInvertSelection.bindAsEventListener(this, true));
          Event.observe(rightInvertSelectionButton, "click", this.onInvertSelection.bindAsEventListener(this, false));
          Event.observe(leftSelectAllButton, "click", this.onSelectAllClick.bindAsEventListener(this, true));
          Event.observe(rightSelectAllButton, "click", this.onSelectAllClick.bindAsEventListener(this, false));
          

		  // This for the MultiSelectAction Bean. 
		  //If actionBean list is less than 1, button is displayed and not the dropdown     
		  if ( leftSelects.length > 1 )
		  {    
	          this.actionBeanLeftSelect = $(leftSelects[1]);
	          this.actionBeanRightSelect = $(rightSelects[1]);
              var actionBeanLeftGoBox = $(leftInputs[2]);
	          var actionBeanRightGoBox = $(leftInputs[2]);
	          Event.observe( actionBeanLeftGoBox, "click", this.actionBeanFunc.bindAsEventListener(this, true));
	          Event.observe( actionBeanRightGoBox, "click", this.actionBeanFunc.bindAsEventListener(this, false));
          }
        }
    },
    actionBeanFunc: function (event, leftSelect ) {
    	var destination = this.actionBeanLeftSelect ; 
    	var selectedBox = this.leftSelectBox;
    	if ( !leftSelect ) 
    	{
	    	destination = this.actionBeanRightSelect ;
	    	selectedBox = this.rightSelectBox ;
	    }
	    var myindex=destination.selectedIndex;
	    if( myindex == -1 || myindex > destination.length-1)
	    {
	      alert(msg);
	      return false;
	    }
	    var sFunctionName = destination.options[myindex].value;
	    var oFunc = window[sFunctionName];
	    oFunc(selectedBox.name, this.formName);  
	    this.setHiddenValues();
    },
    /*
     *  listener registration for leftmove and rightmove clicks
     */
     addToLeftClickListener: function(listenerFunc) {
     	if(this.leftClickListeners != null)
		this.leftClickListeners.push(listenerFunc);
	},
	
	addToRightClickListener: function(listenerFunc) {
		if(this.rightClickListeners != null)
		this.rightClickListeners.push(listenerFunc);
	},
	
	 removeFromLeftClickListener: function(listenerFunc) {
	 	if(this.leftClickListeners != null)
		this.leftClickListeners.remove(listenerFunc);
	},
	
	removeFromRightClickListener: function(listenerFunc) {
		if(this.rightClickListeners != null)
		this.rightClickListeners.remove(listenerFunc);
	},
	
    removeAllLeftClickListeners: function() {
		this.leftClickListeners =[];
	},
	
	removeAllRightClickListeners: function() {
		this.rightClickListeners =[];
	},
   
     removeFromLeft: function(id){     
     	if(this.leftSelectBox != null){	
     	var leftItems = this.leftSelectBox.immediateDescendants();
     	var toRemoveElement = leftItems.find(function(item){
     		return !item.selected && item.value == id;
     	});
     	if(toRemoveElement != null)
     	{
	      	Element.remove(toRemoveElement);
	    	this.setHiddenValues();
	    }
     	}
     },
  
   addToLeft: function(id, value){
   if(this.leftSelectBox != null){
      var leftItems = this.leftSelectBox.immediateDescendants();
      var returnItem = leftItems.find(function(item){
     		return item.value == id;
     	});
     exists = (returnItem != null) ? true : false;
     if(!exists) 
     { 
     	this.rawAddToLeft( id, value );
     	this.setHiddenValues();
     }
   }
   },
   
   rawAddToLeft: function(id, value) {
	  var item = document.createElement("option");
      item.value = id;
      item.innerHTML = value;
      this.leftSelectBox.appendChild(item);
   },
   
    
   
     removeFromRight: function(id){
     	  if(this.rightSelectBox != null){
     	var rightItems = this.rightSelectBox.immediateDescendants();
     	var toRemoveElement = rightItems.find(function(item){
     		return !item.selected && item.value== id;
     	});
     	if(toRemoveElement != null)
     	{
	     	Element.remove(toRemoveElement);
	     	this.setHiddenValues();
	    }
      }
     },
  
 	addToRight: function(id, value){
     if(this.rightSelectBox != null){
      var rightItems = this.rightSelectBox.immediateDescendants();
      var returnItem  = rightItems.find(function(item){
     		return item.value == id;
     	});
      exists = (returnItem != null) ? true : false;
      if(!exists)
 	  {	
	       var item = document.createElement("option");
           item.value = id;
           item.innerHTML = value;
           this.rightSelectBox.appendChild(item);
           this.setHiddenValues();
	  }
     }
    },
    
   resetRightBox: function( ){
   	if(this.rightSelectBox != null){
       var rightItems = this.rightSelectBox.immediateDescendants();
       rightItems.invoke("remove");
       this.setHiddenValues();
   	}
    },
    
    resetLeftBox: function( ){
      if(this.leftSelectBox != null){
       var leftItems = this.leftSelectBox.immediateDescendants();
       leftItems.invoke("remove");
       this.setHiddenValues();
      }
    },
    
    getAllLeftAvailableElements : function(){
    	if(this.leftSelectBox != null)
    	return this.leftSelectBox.immediateDescendants();
    	else
    	return [];
    },
    
    getAllRightElements : function(){
    	 if(this.rightSelectBox != null)
    	 return this.rightSelectBox.immediateDescendants();
    	 else
    	 return [];
    },
    
    onMoveLeftClick: function(event)
    {
    	
        var rightItems = this.rightSelectBox.immediateDescendants();
        var selectedItems = rightItems.findAll(function(item)
        {
            return item.selected;
        });
        if ( selectedItems == null || selectedItems.length == 0 )
        {
        	alert(page.bundle.getString("admin.manageuserlists.selectionwarning"));
        	return;
         }
        selectedItems.invoke("remove");
        var lastItem = null;
        selectedItems.each(function (item)
        {
            this.leftSelectBox.insertBefore(item, lastItem);
            lastItem = item;
        }.bind(this));
        this.setHiddenValues();
        if( this.leftClickListeners)
      {
         this.leftClickListeners.each( function ( listenerFunc ) { 
         	listenerFunc.apply( this, selectedItems )
         }.bind(this) );
         
      }

    },

    onMoveRightClick: function(event)
    {
    
        var leftItems = this.leftSelectBox.immediateDescendants();
        var selectedItems = leftItems.findAll(function(item)
        {
            return item.selected;
        });
        if ( selectedItems == null || selectedItems.length == 0 )
        {
        	alert(page.bundle.getString("admin.manageuserlists.selectionwarning"));
        	return;
         }
        selectedItems.invoke("remove");       
        var lastItem = null;
        selectedItems.each(function (item)
        {
            this.rightSelectBox.insertBefore(item, lastItem);
            lastItem = item;
        }.bind(this));
        this.setHiddenValues();
        if(this.rightClickListeners)
        {
         this.rightClickListeners.each( function ( listenerFunc ) { 
         	listenerFunc.apply( this, selectedItems )
         }.bind(this) );
        }
    },

    setHiddenValues: function()
    {
    
        var leftString;
        var rightString;
        var temp = "";
    
        //Populate select box values comma separated into leftString,rightString.    
        if(this.leftSelectBox != null ){
	        this.leftSelectBox.immediateDescendants().each(function(option)
	        {
	            leftString = option.value;
	            temp += leftString + ",";
	        })
	        temp = temp.substring(0, temp.length - 1);
	        temp = temp.replace(/^\s*|\s*$/g, "");
	        this.leftValues.value = temp;
	        temp = "";
        }
        if(this.rightSelectBox != null ){
	        this.rightSelectBox.immediateDescendants().each(function(option)
	        {
	            rightString = option.value;
	            temp += rightString + ",";
	        })
	        temp = temp.substring(0, temp.length - 1);
	        temp = temp.replace(/^\s*|\s*$/g, "");
	        this.rightValues.value = temp;
	        temp = "";
        }
    },

    onSelectAllClick: function(event, isLeft)
    {
        if (isLeft)
        {
            this.leftSelectBox.immediateDescendants().each(function(option)
            {
                option.selected = true;
            });
        }
        else
        {
            this.rightSelectBox.immediateDescendants().each(function(option)
            {
                option.selected = true;
            });
        }
        Event.stop(event);
    },

    onInvertSelection: function(event, isLeft)
    {
        if (isLeft)
        {
            this.leftSelectBox.immediateDescendants().each(function(option)
            {
                option.selected = !option.selected;
            });
        }
        else
        {
            this.rightSelectBox.immediateDescendants().each(function(option)
            {
                option.selected = !option.selected;
            });
        }
    }
}    

/**
 * A dynamic picker list
 */
widget.PickerList = Class.create();
widget.PickerList.prototype = {
    /**
     * Creates a new picker list
     * @param id id of the picker list table
     * @param cellGenerators an array of functions to be called to generate the HTML for the cells for 
     *        a new row in the table.
     * @param columnAlignments an array of the alignments of the columns
     * @param reorderable whether the table is to be reorderable
     * @param reorderingUrl url that reordering changes will be persisted to (can be null)
     * @param contextParameters parameters that are passed along with the reordering action.
     */
    initialize: function( id, cellGenerators, columnAlignments, reorderable, reorderingUrl, contextParameters )
    {
        this.table = $(id);
        this.reorderable = reorderable;
        if ( this.table )
        {
            this.tableBody = $(this.table.getElementsByTagName('tbody')[0]);
            if ( reorderable )
            {
            	this.dragDrop = new dragdrop.ListReordering( this.tableBody, this.table.id + '_reorderControls', false, 'tr', 'dndHandle', 'span', reorderingUrl, contextParameters, new Date().getTime(), null );
            }
        }        
        this.cellGenerators = cellGenerators;
        this.columnAlignments = columnAlignments;
    },
    
    /**
     * This function takes any number of arguments.  They will be passed
     * directly to the generator functions.
     * 
     * If this list is reorderable, the first two arguments must be:
     *  - id of the item added.
     *  - name of the item added.
     */
    addRow: function()
    {
        var generatorArgs = arguments;
        var row = $(document.createElement("tr"));
        if ( this.reorderable )
        {
           var id = arguments[0];
           var name = arguments[1];
           //Set the row id so that the drag and drop code can identify the row
           row.id = this.table.id + '_row:' + id;
           //Add the reordering handle.
           var cell = document.createElement("td");
           cell.className = 'smallCell dndHandle';
           cell.valign = 'top';
           cell.innerHTML = '<span class="reorder"><img src="/images/ci/icons/generic_updown.gif" alt="" /></span>';
           row.appendChild( cell );
           //Add the item to the accessible controls.
           var accessibleSelect = $(this.table.id + "_reorderControlsSelect");
           accessibleSelect.options[accessibleSelect.length] = new Option( name, id );
        }
        this.cellGenerators.each( function( generator, index )
        {
            var alignment  = this.columnAlignments[index]; 
            var cell = document.createElement("td");
            cell.setAttribute("align", alignment);
            cell.innerHTML = generator.apply( window, generatorArgs );
            row.appendChild( cell ); 
        }.bind(this));
        this.tableBody.appendChild( row );       
        if ( this.reorderable )
        {
            //Toggle drag and drop so that it picks up the new item.
            this.dragDrop.disableDragAndDrop();
            this.dragDrop.enableDragAndDrop();
            this.dragDrop.calculateItemOrder();      
        }
        return row; 
    },
    /**
     * Removes the row with the specified id or index
     * @param idOrIndex
     * - if the argument is a string - it is taken as the id of one of the rows in the table
     * - if the argument is a number - the row at the specified index will be removed.
     */
    removeRow: function( idOrIndex )
    {
    	var rowToRemove = null;
    	if ( Object.isString( idOrIndex ) )
    	{
    		rowToRemove = $(this.table.id + "_row:" + idOrIndex);
    	}
    	else
    	{
    		rowToRemove = this.tableBody.childElements()[idOrIndex];
    	}    	
    	if ( rowToRemove )
    	{
    		//Remove the row from the accessible repositioning controls if applicable
    		if ( this.reorderable )
    		{
    			var idToCheck = rowToRemove.id.split(':')[1];
    			var accessibleSelect = $(this.table.id + "_reorderControlsSelect");
    			var options = accessibleSelect.childElements();
    			for ( var i = 0; i < options.length; i++ )
    			{
    				if ( options[i].value == idToCheck )
    				{
    					Element.remove( options[i] );
    					break;
    				}
    			}
    		}
    		Element.remove( rowToRemove );
    		if ( this.reorderable )
    		{
    			this.dragDrop.calculateItemOrder();
    		}
    	}    
    }
}
widget.PickerList.noopGenerator = function()
{
  return '&nbsp;';
}

/**
 *  File picker
 */
widget.FilePicker = Class.create();
widget.FilePicker.prototype = {
    /**
     * Creates a new file picker
     * @param pickerList the javascript object representing the picker list (of currently attached files)
     * @param baseElementName the base name for the file picker elements
     * @param required whether a file is required to be chosen
     * @param overrideLocalBehavior whether the CS options to override local behavior should be shown
     * @param csPickerUrl url to the CS file picker
     */
    initialize: function( pickerList, baseElementName, required, overrideLocalBehavior, csPickerUrl )
    {
        this.pickerList = pickerList;
        this.baseElementName = baseElementName;
        this.required = required;
        this.overrideLocalBehavior = overrideLocalBehavior;
        this.csPickerUrl = csPickerUrl;

        this.pickCSButton = $( this.baseElementName + '_csBrowse' );
        this.selectedCSFile = $( this.baseElementName + '_selectedCSFile' );
        this.selectedCSFileName = $( this.baseElementName + '_selectedCSFileName' );
        this.selectedCSFileSize = $( this.baseElementName + '_selectedCSFileSize' );
        this.pickLocalButton = $( this.baseElementName + '_localBrowse');
        this.localFilePicker = $( this.baseElementName + '_chooseLocalFile');
        this.selectedFileActionsArea = $( this.baseElementName + '_selectedFileActions');
        this.selectedFileName = $( this.baseElementName + '_selectedFileName');
        this.selectedFileSource = $( this.baseElementName + '_selectedFileSource');
        this.selectedFileLinkTitle = $( this.baseElementName + '_selectedFileLinkTitle');
        this.selectedFileSpecialAction = $( this.baseElementName + '_selectedFileSpecialAction');
        this.attachFileButton = $( this.baseElementName + '_attachFileButton' );
        this.cancelFileButton = $( this.baseElementName + '_cancelFileButton' );
        this.allowMultipleFiles = (this.attachFileButton != null);
        this.allowCS = (this.pickCSButton != null);
        this.allowLocal = (this.pickLocalButton != null);
        
        // Wire up events
        if( this.overrideLocalBehavior )
        {
            this.pickTargetButton = $( this.baseElementName + '_CSTargetButton' );
            this.targetCSLocation = $( this.baseElementName + '_CSTarget' );
            this.pickMDButton = $( this.baseElementName + '_CSTargetMetaButton' );
            CSMetadataPickerCallBack = this.afterPickMD.bind( this );
            Event.observe( this.pickTargetButton, "click", this.onPickTargetClick.bindAsEventListener( this ) );
            Event.observe( this.pickMDButton, "click", this.onPickMDClick.bindAsEventListener( this ) );
        }
        if( this.allowCS )
        {
            Event.observe( this.pickCSButton, "click", this.onCSBrowse.bindAsEventListener( this ) );
            Event.observe( this.selectedCSFile, "change", this.onCSPick.bindAsEventListener( this ) );
        }
        if( this.allowLocal )
        {
            this.localFileContainer = this.localFilePicker.up();
            Event.observe( this.localFilePicker, "change", this.onLocalPick.bindAsEventListener( this ) );
        }
        if( this.allowMultipleFiles )
        {
            Event.observe( this.attachFileButton, "click", this.onAttachClick.bindAsEventListener( this ) );
        }
        Event.observe( this.cancelFileButton, "click", this.onCancelClick.bindAsEventListener( this ) );
        Event.observe( this.cancelFileButton.form, "submit", this.onSubmit.bindAsEventListener( this ) );

        widget.FilePicker.registerFilePicker( this );
    },
    
    /**
     * For the override local behavior: show the picker to pick the location
     */
    onPickTargetClick: function( event )
    {
        var remote = window.open('/webapps/cmsmain/folderpicker/', 'picker_browse', 'width=800,height=500,resizable=yes,scrollbars=yes,status=yes,top=20,left='+(screen.width-800));
        if ( remote != null )
        {
            remote.focus();
            if ( remote.opener == null ) remote.opener = self;
            remote.opener.inputEntryURLToSet = this.targetCSLocation;
            remote.opener.returnFullURL = false;
            remote.methodCall = this.onPickMDClick.bind( this );
        }
    },
    
    /**
     * For the override local behavior: show the picker to pick the metadata
     */
    onPickMDClick: function( event )
    {
        var location = this.targetCSLocation;
        var file = this.localFilePicker;
        if ( location.value == '' || file.value == '')
        {
            return;
        }
        var url = '/webapps/cmsmain/execute/metadatapicker/manage?action=pick&location='+location.value+'&file='+file.value;
        var remote = window.open( url, 'picker_browse', 'width=800,height=500,resizable=yes,scrollbars=yes,status=yes,top=20,left='+(screen.width-800));
        if ( remote != null )
        {
          remote.focus();
          if ( remote.opener == null ) remote.opener = self;
        }
    },
    /**
     * For the override local behavior: callback from the metadata picker
     */
    afterPickMD: function( metadta, selection, synchronised, format )
    {
        $(this.baseElementName + '_CSTargetmetadata').value = metadata;
        $(this.baseElementName + '_CSTargetselection').value = selection;
        $(this.baseElementName + '_CSTargetSynchronised').value = synchronised;
        $(this.baseElementName + '_CSTargetDisplayFormat').value = format;
    },
    
    /**
     * Show the CS file chooser
     */
    onCSBrowse: function( event )
    {
        this.csBrowseWindow = null;        
        var windowId = new Date().getTime();
        this.csBrowseWindow = window.open( this.csPickerUrl, windowId, 'width=800,height=500,resizable=yes,scrollbars=yes,status=yes,toolbar=no,menubar=no,location=no,directories=no,top=20,left='+ (screen.width - 800) );
        if ( this.csBrowseWindow != null )
        {
            this.csBrowseWindow.focus();
            if ( this.csBrowseWindow.opener == null ) this.csBrowseWindow.opener = self;
            this.csBrowseWindow.opener.inputEntryURLToSet = this.selectedCSFile;
            this.csBrowseWindow.opener.returnFullURL = false;
            this.csBrowseWindow.opener.inputFileSizeToSet = this.selectedCSFileSize;
            this.csBrowseWindow.opener.linkName = this.selectedCSFileName;
            this.csBrowseWindow.opener.customHandler = this.onCSPick.bind(this);
        }
        Event.stop( event );
    },
    
    /**
     * Callback called after a file has been chosen from the CS file picker
     */
    onCSPick: function()
    {
        this.csBrowseWindow = null;
	    this.selectedFileSource.value = 'C';
	    this.selectedFileName.innerHTML = this.selectedCSFile.value;
	    if ( this.selectedFileLinkTitle != null )
	    {
	       this.selectedFileLinkTitle.value = this.selectedCSFileName.value;
	    }
     	this.selectedFileActionsArea.show();
	   	this.togglePickerButtons( false );
    },
    
    /**
     * Called after a file is chosen from the local file picker
     */
    onLocalPick: function( event )
    {
        this.selectedFileName.innerHTML = this.getFileName(this.localFilePicker.value);
        this.selectedFileSource.value = 'L';
        this.selectedFileActionsArea.show();
        this.togglePickerButtons( false );
    },
    
    /**
     * Called after the "Attach file" button is clicked (only shows up if more than
     * one file can be attached)
     */
    onAttachClick: function( event )
    {
        var isLocal = this.selectedFileSource.value == 'L';
        var row = this.pickerList.addRow( this, this.selectedFileSource.value == 'L' );
        var cell = $(row.getElementsByTagName('td')[0]);
        if ( isLocal )
        {
            Element.remove( this.localFilePicker );
            this.localFilePicker.removeClassName("hiddenInput");
            this.localFilePicker.setStyle({position: "absolute", left: '-1000px'});
            this.localFilePicker.disabled = false;
            cell.appendChild( this.localFilePicker );
        }
        //Set up the names of the local file fields
        this.pickerList.tableBody.getElementsBySelector('input[type="file"]').each( function( item, index )
        {
            item.name = this.baseElementName + '_LocalFile' + index;
        }.bind(this));
        this.selectedFileActionsArea.hide();
        this.clearSelectedFileInfo();
        this.togglePickerButtons( true );
        Event.stop( event );
    },
    
    /**
     * Called when the "Do not attach file" button is clicked
     */
    onCancelClick: function( event )
    {
        this.selectedFileActionsArea.hide();
        this.clearSelectedFileInfo();
        this.togglePickerButtons( true );
        Event.stop( event );
    },
    
    /**
     * Toggles the enabled state of the Local/CS picker buttons to the specified state
     */
    togglePickerButtons: function( enabled )
    {
        if ( this.allowLocal )
        {
            this.pickLocalButton.disabled = !enabled;
            if (enabled) {
                this.localFilePicker.position = 'relative';
                this.localFilePicker.style.left = '';
            } else {
                this.localFilePicker.position = 'absolute';
                this.localFilePicker.style.left = '-1000px';
            }
            if ( this.allowMultiple )
            {
                this.localFilePicker.disabled = !enabled;
            }
        }
        if ( this.allowCS )
        {
            this.pickCSButton.disabled = !enabled;
        }       
    },
    
    /**
     * Clears the info associated to the current attached file (if the user cancelled, or chose
     * to attach another file )
     */
    clearSelectedFileInfo: function()
    {
        var isLocal = this.selectedFileSource.value == 'L';
        this.selectedFileName.innerHTML = "";
        this.selectedFileSource.value = "";
        if ( this.selectedFileLinkTitle != null ) this.selectedFileLinkTitle.value= "";
        if ( this.selectedFileSpecialAction != null ) this.selectedFileSpecialAction.selectedIndex = 0;
        if ( isLocal )
        {
            var title = "";
            if ( !this.allowMultipleFiles )
            {
              title = this.localFilePicker.title;
              Element.remove( this.localFilePicker );
            }
            this.localFilePicker = $(document.createElement("input"));
            if ( !this.allowMultipleFiles )
            {
                this.localFilePicker.name = this.baseElementName + '_LocalFile0';
            }
            this.localFilePicker.title = title;
            this.localFilePicker.type = "file";
            this.localFilePicker.addClassName("hiddenInput");
            this.localFileContainer.insertBefore( this.localFilePicker, this.localFileContainer.firstChild );
            Event.observe( this.localFilePicker, "change", this.onLocalPick.bindAsEventListener( this ) );
        }
        else
        {
            this.selectedCSFile.value = "";
            this.selectedCSFileName.value = "";
            this.selectedCSFileSize.value = "";                        
        }
    },
    
    /**
     * Gets the file name based on the full file path.
     */
    getFileName: function( fullPath )
    {
        var result = fullPath;
        var lastIndexOfBackslash = fullPath.lastIndexOf('\\');
        var lastIndexOfSlash = fullPath.lastIndexOf('/');
        if ( lastIndexOfBackslash > lastIndexOfSlash )
        {
            result = fullPath.substring( lastIndexOfBackslash + 1, fullPath.length );
        }
        else if ( lastIndexOfSlash > lastIndexOfBackslash )
        {
            result = fullPath.substring( lastIndexOfSlash + 1, fullPath.length );
        }
        return result;                
    },
    
    setRequired: function( required )
    {
    	this.required = required;
    },

    /**
     * Validates the form when it is submitted.
     */
    onSubmit: function( event )
    {
        //Validate the form if necessary
        if ( this.required )
        {
	        if ( this.allowMultipleFiles )
	        {
	            if ( this.pickerList.tableBody.immediateDescendants().length == 0 )
	            {
	                alert( page.bundle.getString("filePicker.validate.atLeastOne") );
	                Event.stop( event );
	                return;
	            }
	        }
	        else
	        {
	            if ( (this.selectedCSFile != null && this.selectedCSFile.value == '') &&
	                 (this.localFilePicker != null && this.localFilePicker.value == '') )
	            {
	                alert( page.bundle.getString("filePicker.validate.one") );
	                Event.stop( event );
	                return;
	            }
	        }
        }
    }
        
}

/**
 * Toggles the "mark for removal" status of an item in the currently attached
 * files table.  Should be called from an onclick attribute on the toggle link
 * in the table.
 */
widget.FilePicker.toggleForRemove = function( event, removeLink )
{
  var e = event || window.event;
  var tableRow = removeLink.up("tr");
  var hiddenField = removeLink.up("td").down('input[type="hidden"]');
  
  tableRow.toggleClassName("removeCell");
  if ( hiddenField.disabled )
  {
    hiddenField.disabled = false;
    removeLink.innerHTML = page.bundle.getString("filePicker.unmarkForRemove");  
  }
  else
  {
    hiddenField.disabled = true;
    removeLink.innerHTML = page.bundle.getString("filePicker.markForRemove");
  }
  Event.stop( e );
};

/**
 * Removes the specified pending attachment.  Should be called from an 
 * onclick handler on a link in the currently attached files table
 */
widget.FilePicker.removePendingAttachment = function( event, removeLink )
{
  var e = event || window.event;
  if ( confirm( page.bundle.getString("filePicker.doNotAttach.confirm") ) )
  {
    Element.remove( removeLink.up("tr") );
  }
  Event.stop( e );
};

/**
 * A registry of defined file pickers and methods to access this registry
 */
widget.FilePicker.filePickers = {};
widget.FilePicker.registerFilePicker = function( filePicker )
{
 widget.FilePicker.filePickers[filePicker.baseElementName] = filePicker;
};
widget.FilePicker.unRegisterFilePicker = function( filePicker )
{
 delete widget.FilePicker.filePickers[filePicker.baseElementName];
};
widget.FilePicker.getFilePicker = function( baseElementName )
{
 return widget.FilePicker.filePickers[baseElementName];
};

/**
 * Cell generators for the current attached files table
 */
widget.FilePicker.cellGenerators = {
    fileName: function( filePicker, isLocal )
    {
        var result = '<input type="hidden" name="'+filePicker.baseElementName+'_attachmentType" value="'+(isLocal?'L':'C')+'">';
        result += '<input type="hidden" name="'+filePicker.baseElementName+'_fileId" value="new">';
        if ( isLocal )
        {
            result += '<span class="fileName"><img src="/images/ci/ng/cal_year_event.gif" alt="'+page.bundle.getString('common.file')+'"> '+filePicker.getFileName(filePicker.localFilePicker.value)+'</span>';
        }
        else
        {
            result += '<span class="fileName"><img src="/images/ci/ng/cal_year_event.gif" alt="'+page.bundle.getString('common.file')+'"> '+filePicker.selectedCSFile.value+'</span>';
            result += '<input type="hidden" name="'+filePicker.baseElementName+'_CSFile" value="'+filePicker.selectedCSFile.value+'">';
        }
        return result;
    },
    fileType: function( filePicker, isLocal )
    {
        var result = null;
        if ( isLocal )
        {
            result = page.bundle.getString("filePicker.fileType.attachment");
        }
        else
        {
            result = page.bundle.getString("filePicker.fileType.content");
        }
        return result;
    },
    linkTitle: function( filePicker, isLocal )
    {
        var linkTitle = "";
        if ( filePicker.selectedFileLinkTitle != null )
        {
            linkTitle = filePicker.selectedFileLinkTitle.value;
        }
        return '<input type="text" name="'+filePicker.baseElementName+'_linkTitle" value="'+linkTitle+'">';    
    },
    specialAction: function( filePicker, isLocal )
    {
        return '<input type="hidden" name="'+filePicker.baseElementName+'_specialAction" value="'+filePicker.selectedFileSpecialAction.options[filePicker.selectedFileSpecialAction.selectedIndex].value+'">' + filePicker.selectedFileSpecialAction.options[filePicker.selectedFileSpecialAction.selectedIndex].text;
    },
    size: function( filePicker, isLocal )
    {
        if ( !isLocal && filePicker.selectedCSFileSize != null )
        {
            return '<input type="hidden" name="'+filePicker.baseElementName+'_size" value="'+filePicker.selectedCSFileSize.value+'"> ' + filePicker.selectedCSFileSize.value;
        }
        else
        {
            return "";
        }
    },
    remove: function( filePicker, isLocal )
    {
      return '<a href="#" onclick="widget.FilePicker.removePendingAttachment(event, this);">' + page.bundle.getString("filePicker.doNotAttach") + '</a>';
    }
};

widget.InlineSingleCSFilePicker = Class.create();
widget.InlineSingleCSFilePicker.prototype = 
{
    initialize: function( baseElementName, csPickerUrl )
    {
		this.baseElementName = baseElementName;
		this.csPickerUrl = csPickerUrl;
		this.browseButton = $(baseElementName + '_csBrowse' );
		this.fileEntry = $(baseElementName + '_CSFile' );
		this.fileId = $(baseElementName + '_fileId' );
		
		Event.observe( this.browseButton, 'click', this.onCSBrowse.bindAsEventListener( this ) );
    },
    
    /**
     * Show the CS file chooser
     */
    onCSBrowse: function( event )
    {
        this.csBrowseWindow = null;        
        var windowId = new Date().getTime();
        this.csBrowseWindow = window.open( this.csPickerUrl, windowId, 'width=800,height=500,resizable=yes,scrollbars=yes,status=yes,toolbar=no,menubar=no,location=no,directories=no,top=20,left='+ (screen.width - 800) );
        if ( this.csBrowseWindow != null )
        {
            this.csBrowseWindow.focus();
            if ( this.csBrowseWindow.opener == null ) this.csBrowseWindow.opener = self;
            this.csBrowseWindow.opener.inputEntryURLToSet = this.fileEntry;
            this.csBrowseWindow.opener.returnFullURL = false;
            this.csBrowseWindow.opener.linkName = this.fileId;
        }
        Event.stop( event );
    }
};

/**
 * Inline single local file picker
 *   - $baseElementName_attachmentType - 'AL' or 'L' or ''
 *   - $baseElementName_localBrowse
 *   - $baseElementName_fileId
 *
 */
widget.InlineSingleLocalFilePicker = Class.create();
widget.InlineSingleLocalFilePicker.prototype = 
{
    initialize: function( baseElementName, currentAttachedFile, required )
    {
      this.baseElementName = baseElementName;
      this.fileInput = $(baseElementName + '_chooseLocalFile');
      this.fileInputWrapper = $(this.fileInput.parentNode);
      this.attachmentType = $(baseElementName + '_attachmentType');
      this.fullFileName = $(baseElementName + '_fileId');
      this.attachmentNameSpan = $(baseElementName + '_attachmentName');
      this.removeLink = $(baseElementName + '_removeLink');
      this.inputArea = $(baseElementName + '_inputArea');
      this.attachedFileArea = $(baseElementName + '_attachedFileArea');
      //Wire up events
      Event.observe( this.fileInput, "change", this.onAfterChooseFile.bindAsEventListener( this ) );
      Event.observe( this.removeLink, "click", this.onRemoveClick.bindAsEventListener( this ) );
      Event.observe( this.fileInput.form, "submit", this.onSubmit.bindAsEventListener( this ) );
      //Set up initial values
      if ( currentAttachedFile != null && currentAttachedFile != '' )
      {
        this.setDefaultCurrentAttachedFile( currentAttachedFile );
      }      
      widget.InlineSingleLocalFilePicker.pickerMap[baseElementName] = this;
    },
    setCurrentAttachedFile: function( file )
    {
      this.clearFileInput();
      if ( file != null && file != '' )
      {
        this.attachmentType.value = 'AL';
        this.attachmentNameSpan.innerHTML = '<a href="'+file+'" target="_new">' + this.getFileName( file ) + '</a>';
        if ( this.removeHiddenField )
        {
          Element.remove( this.removeHiddenField );
          this.removeHiddenField = null;
        }
        widget.ShowUnsavedChanges.changeHiddenValue( this.fullFileName, file );
        this.inputArea.setStyle({position: "absolute", left: '-1000px'});
        this.attachedFileArea.setStyle({position: "static", left: ''});
      }
      else
      {
        this.attachmentNameSpan.innerHTML = '';
        this.attachmentType.value = '';
        widget.ShowUnsavedChanges.changeHiddenValue( this.fullFileName, '');
        this.inputArea.setStyle({position: "static", left: ''});
        this.attachedFileArea.setStyle({position: "absolute", left: '-1000px'});  
      }
    },
    setDefaultCurrentAttachedFile: function( file )
    {
      this.clearFileInput();
      if ( file != null  && file != '' )
      {
        this.attachmentType.value = 'AL';
        this.attachmentType._defaultValue = 'AL';
        this.attachmentNameSpan.innerHTML = '<a href="'+file+'" target="_new">' + this.getFileName( file ) + '</a>';
        if ( this.removeHiddenField )
        {
          Element.remove( this.removeHiddenField );
          this.removeHiddenField = null;
        }        
        this.fullFileName.value = file;
        this.fullFileName._defaultValue = file;
        this.inputArea.setStyle({position: "absolute", left: '-1000px'});
        this.attachedFileArea.setStyle({position: "static", left: ''});
      }
      else
      {
        this.attachmentNameSpan.innerHTML = '';
        this.attachmentType.value = '';
        this.fullFileName.value = '';      
        this.inputArea.setStyle({position: "static", left: ''});
        this.attachedFileArea.setStyle({position: "absolute", left: '-1000px'});      
      }
    },    
    onAfterChooseFile: function( event )
    {
      this.attachmentNameSpan.innerHTML = this.getFileName( this.fileInput.value );
      this.attachmentType.value = 'L';
      if ( this.removeHiddenField )
      {
        Element.remove( this.removeHiddenField );
        this.removeHiddenField = null;
      }
      widget.ShowUnsavedChanges.changeHiddenValue( this.fullFileName, this.fileInput.value );
      this.inputArea.setStyle({position: "absolute", left: '-1000px'});
      this.attachedFileArea.setStyle({position: "static", left: ''});
      Event.stop( event );
    },
    onRemoveClick: function( event )
    {
      this.clearFileInput();
      if ( this.attachmentType.value == 'AL' )
      {
        this.removeHiddenField = document.createElement('input');
        this.removeHiddenField.type = 'hidden';
        this.removeHiddenField.name = this.baseElementName + '_remove';
        this.removeHiddenField.id = this.baseElementName + '_remove';
        this.removeHiddenField.value = this.fullFileName.value;
        this.attachedFileArea.insertBefore( this.removeHiddenField, this.attachedFileArea.firstChild );
        widget.ShowUnsavedChanges.changeHiddenValue(this.fullFileName, this.fullFileName.value);
      }
      else
      {
        this.attachmentType.value = '';
        widget.ShowUnsavedChanges.changeHiddenValue(this.fullFileName, '');
      }
      this.attachmentNameSpan.innerHTML = '';      
      
      this.inputArea.setStyle({position: "static", left: ''});
      this.attachedFileArea.setStyle({position: "absolute", left: '-1000px'});
      Event.stop( event );
    },
    clearFileInput: function()
    {
      var title = this.fileInput.title;
      Element.remove( this.fileInput );
      this.fileInput = $(document.createElement("input"));
      this.fileInput.title = title;
      this.fileInput.type = "file";
      this.fileInput.addClassName("hiddenInput");
      this.fileInput.name = this.baseElementName + '_LocalFile0';
      this.fileInput._defaultValue = '';
      this.fileInputWrapper.insertBefore( this.fileInput, this.fileInputWrapper.firstChild );
      Event.observe( this.fileInput, "change", this.onAfterChooseFile.bindAsEventListener( this ) );    
    },   
    /**
     * Gets the file name based on the full file path.
     */
    getFileName: function( fullPath )
    {
        var result = fullPath;
        var lastIndexOfBackslash = fullPath.lastIndexOf('\\');
        var lastIndexOfSlash = fullPath.lastIndexOf('/');
        if ( lastIndexOfBackslash > lastIndexOfSlash )
        {
            result = fullPath.substring( lastIndexOfBackslash + 1, fullPath.length );
        }
        else if ( lastIndexOfSlash > lastIndexOfBackslash )
        {
            result = fullPath.substring( lastIndexOfSlash + 1, fullPath.length );
        }
        return result;                
    },  
    /**
     * Validates the form when it is submitted.
     */
    onSubmit: function( event )
    {
        //Validate the form if necessary
        if ( this.required )
        {
            if ( this.fullFileName.value == '' )
            {
                alert( page.bundle.getString("filePicker.validate.one") );
                Event.stop( event );
                return;
            }
        }
    }    
};
widget.InlineSingleLocalFilePicker.pickerMap = {};

widget.UserRoleSelect= Class.create();
widget.UserRoleSelect.prototype = {
	initialize: function( userSelectRoleDivStr, moveMsgJS, noRoleMsgJs )
    {
     	this.sourceValueName = "_left_values";
     	this.secondaryValueName = "_right_values";
     	this.primaryValueName = "_primary_value";
		
		this.userSelectRoleDiv = $(userSelectRoleDivStr);
		if ( this.userSelectRoleDiv != null ) {
		    var selects = this.userSelectRoleDiv.getElementsByTagName('select');
		    var inputs = this.userSelectRoleDiv.getElementsByTagName('input');
		    var links = this.userSelectRoleDiv.getElementsByTagName('a');
			this.source = $(selects[0]);
			this.primary = $(inputs[3]);
			this.secondary = $(selects[1]);

			this.leftValues =  $(inputs[0]);
			this.rightValues = $(inputs[1]);
			this.primaryValue = $(inputs[2]);

			this.toPrimaryMove = $(links[0]);
			this.toSecondaryMove = $(links[1]);
			this.toSourceMove = $(links[2]);
			Event.observe(this.toSourceMove, "click", this.switchUserRoleColumns.bindAsEventListener(this, false,moveMsgJS,noRoleMsgJs));
			Event.observe(this.toPrimaryMove, "click", this.switchPrimary.bindAsEventListener(this, moveMsgJS));
			Event.observe(this.toSecondaryMove, "click", this.switchUserRoleColumns.bindAsEventListener(this, true,moveMsgJS,noRoleMsgJs));
		}
    },
    
	switchPrimary : function ( event, msg ) {
		var indx;
		indx=0;
		
		var sourceArray = this.source;
		
		if (sourceArray.selectedIndex == -1 || sourceArray.selectedIndex > sourceArray.length-1)
		{
		  alert(msg);
		  return false;
		}
		if (sourceArray.selectedIndex >= 0)
		{
		  indx =sourceArray.selectedIndex;
		  if( indx == -1 || indx > sourceArray.length-1)
		      {
		         alert(msg);
		         return false;
		      }
		    tmpOpt = this.getFromPrimary();
		    
		    this.primaryValue.value=sourceArray.options[indx].value; 
		    this.primary.value = sourceArray.options[indx].text;
		    
		    sourceArray.options[indx].selected=false;
		    sourceArray.options[indx]=null;
		    sourceArray.options[sourceArray.length] = tmpOpt;
		}
		this.writeToSelectBoxValues( this.source ,this.leftValues );
		return false;
	},
	getFromPrimary: function () {
		var primaryRoleField = this.primaryValue;
		var primaryField = this.primary;
		return new Option( primaryField.value, primaryRoleField.value);
	},
	writeToSelectBoxValues: function( selectBox, hiddenName )
	{
		var i = 0;
		var values = "";
		while( i < selectBox.length )
		{
		  if( i  > 0)
		  {
		    values += ",";
		  }
		  values += selectBox.options[i].value;
		  i++;
		}
		hiddenName.value  = values;
		return true;
	},
	
	switchUserRoleColumns: function (event, isSourceDest, msg, noRoleMsg)
	{
		var indx;
		indx=0;
		
		sourceArray = this.source;
		targetArray = this.secondary;
		
		if ( !isSourceDest  ) // If we are moving from Dest to Source 
		{
			var temp = sourceArray;
			sourceArray = targetArray;
			targetArray = temp; 
		}
		
		if (sourceArray.length <=0) {
		   alert(noRoleMsg);
		   return false;
		
		}
		if (sourceArray.selectedIndex == -1 || sourceArray.selectedIndex > sourceArray.length-1 )
		{
		  alert(msg);
		  return false;
		}
		var rightIndex=0;
		var targetLength = targetArray.length;
		while (sourceArray.selectedIndex >= 0)
		{
		  indx =sourceArray.selectedIndex;
		  if( indx == -1 || indx > sourceArray.length-1)
		      {
		         alert(msg);
		         return false;
		      }
		
		  tmpOpt = this.cloneMultipleRows(sourceArray.options[indx]);
		  if (targetLength>0) {
		      var i=targetLength;
		
		      while(i >0){
		          tmpOpt1 = this.cloneMultipleRows(targetArray.options[i+rightIndex-1]);
		          targetArray.options[i+rightIndex] = tmpOpt1;
		          i--;
		      }
		  }
		  sourceArray.options[indx].selected=false;
		  targetArray.options[rightIndex] = tmpOpt;
		  //targetArray.options[rigthIndex].selected=true;
		  rightIndex = rightIndex+1;
		  sourceArray.options[indx] = null;
		}  //end of while
		this.writeToSelectBoxValues( this.source, this.leftValues ); 
		this.writeToSelectBoxValues( this.secondary, this.rightValues );

		return false;
	},
	cloneMultipleRows: function (opt)
	{
	    return new Option( opt.text, opt.value, opt.defaultSelected, opt.selected);
	}
};

widget.StepGroup = {};
widget.StepGroup.toggleStepGroup = function( e )
{
  var event = e || window.event;
  var target = Event.findElement( event, 'li' );
  var tabs = $A($('dataCollectionContainer').getElementsByTagName('ul')[0].getElementsByTagName('li'));
  tabs.each( function( tab )
  {
    tab = $(tab);
    if ( tab.id == target.id )
    {
      tab.addClassName("active");
      $(tab.getAttribute("bb:groupId")).show();
    }
    else
    {
      tab.removeClassName("active");    
      $(tab.getAttribute("bb:groupId")).hide();
    }
  });    
  Event.stop( event );
};
/**
 * Show a specific step group
 * @param number - the number of the group in order of the tabs at the top 
 * (e.g. 1 is the leftmost tab, then 2, 3, etc.)
 */
widget.StepGroup.showStepGroup = function( number )
{
  var target = $('stepGroupTab_' + number);
  var tabs = $A($('dataCollectionContainer').getElementsByTagName('ul')[0].getElementsByTagName('li'));
  tabs.each( function( tab )
  {
    tab = $(tab);
    if ( tab.id == target.id )
    {
      tab.addClassName("active");
      $(tab.getAttribute("bb:groupId")).show();
    }
    else
    {
      tab.removeClassName("active");    
      $(tab.getAttribute("bb:groupId")).hide();
    }
  });      
}
widget.StepGroup.showAllStepGroupsForSubmit = function()
{
  var tabs = $A($('dataCollectionContainer').getElementsByTagName('ul')[0].getElementsByTagName('li'));
  tabs.each( function( tab )
  {
    $(tab.getAttribute("bb:groupId")).show();
  });  
};
widget.StepGroup.revertAllStepGroupsAfterSubmit = function()
{
  var tabs = $A($('dataCollectionContainer').getElementsByTagName('ul')[0].getElementsByTagName('li'));
  tabs.each( function( tab )
  {
    if ( page.util.hasClassName(tab, 'active') )
    {
      $(tab.getAttribute("bb:groupId")).show();
    }
    else
    {
      $(tab.getAttribute("bb:groupId")).hide();
    }
  });  
};
widget.ShowUnsavedChanges = Class.create();
widget.ShowUnsavedChanges.prototype = 
{
  initialize: function( dataCollectionContainer )
  { 
    widget.ShowUnsavedChanges.enabled = true;
    var container = $(dataCollectionContainer);
    var inputs = $A(container.getElementsByTagName('input'));
    var selects = $A(container.getElementsByTagName('select'));
    var textareas = $A(container.getElementsByTagName('textarea'));
    inputs.each( function( input )
    {
      input = $(input);
      var type = input.type.toLowerCase();
      if ( type == 'checkbox' || type == 'radio' )
      {
        input._defaultValue = input.checked;
      } else if ( type == 'hidden' || type == 'text' )
      {
        input._defaultValue = input.value;
      } else
      {
        input._defaultValue = '';
      }
      if ( type != 'hidden' && type != 'button' && type != 'submit' )
      {
        input.observe( 'change', widget.ShowUnsavedChanges.onValueChange.bindAsEventListener() );
      }
    }.bind(this));
    selects.each( function( input ) //TODO: multiselect?
    {
      input = $(input);
      input._defaultValue = input.selectedIndex;
      input.observe( 'change', widget.ShowUnsavedChanges.onValueChange.bindAsEventListener() );
    }.bind(this));
    textareas.each( function( input )
    {
      input = $(input);
      input._defaultValue = input.value;
      input.observe( 'change', widget.ShowUnsavedChanges.onValueChange.bindAsEventListener() );
    }.bind(this));
  }
};
widget.ShowUnsavedChanges.dataElementsByStepGroup = {};
widget.ShowUnsavedChanges.onValueChange = function( event, elem )
{
    if ( widget.ShowUnsavedChanges.enabled )
    {
	    var dataElement = null;
	    if ( event )
	    {
	      dataElement = Event.findElement( event, 'li' );
	    } else
	    {
	      dataElement = elem.parentNode;
	      while ( dataElement != null && dataElement.tagName.toLowerCase() != 'li' )
	      {
	        dataElement = dataElement.parentNode;
	        if ( dataElement.tagName.toLowerCase() == 'body' )
            {
              dataElement = null;
            }
	      }
	      if ( dataElement != null )
	      {
	        dataElement = $(dataElement);
	      }
	    }    
	    if ( !dataElement )
	    {
	      return;
	    }
	    
	    var isDefault = true;
	    var inputs = $A(dataElement.getElementsByTagName('input'));
	    var selects = $A(dataElement.getElementsByTagName('select'));
	    var textareas = $A(dataElement.getElementsByTagName('textarea'));
	    inputs.each( function( input )
	    {
	      var type = input.type.toLowerCase();
	      if ( type == 'checkbox' || type == 'radio' )
	      {
	        isDefault &= (input.checked == input._defaultValue );
	      } else if ( type == 'hidden' || type == 'text' )
	      {
	        isDefault &= (input.value == input._defaultValue );
	      }
	    });
	    selects.each( function( input ) //TODO: multiselect?
	    {
	      isDefault &= (input.selectedIndex == input._defaultValue );
	    });
	    textareas.each( function( input )
	    {
	      isDefault &= (input.value == input._defaultValue );
	    });    
	    var imgs = dataElement.getElementsByTagName('img');
	    var unsavedImg = null;
	    for ( var i = 0; i < imgs.length; i++ )
	    {
	       if ( imgs[i].className.indexOf('unsavedChangeImg') >= 0 )
	       {
	         unsavedImg = $(imgs[i]);
	         break;
	       }
	    }
	    if ( unsavedImg != null )
	    {
		    if ( isDefault )
		    {
		      dataElement.removeClassName('dirty');
		      unsavedImg.hide(); 
		    }
		    else
		    {
		      dataElement.addClassName('dirty');
		      unsavedImg.show();
		    }    
		    widget.ShowUnsavedChanges.updateStepGroupIndicator(dataElement, !isDefault);
	    }
    }
};
widget.ShowUnsavedChanges.updateStepGroupIndicator = function( dataElement, isDirty )
{
  if ( widget.ShowUnsavedChanges.enabled )
  {
    var tabs = $('dataCollectionContainer').getElementsByTagName('ul')[0].getElementsByTagName('li');
    if ( tabs.length > 0 && tabs[0].parentNode.parentNode.id == 'dataCollectionContainer' )
    {
      for( var t = 0; t < tabs.length; t++ )
      {
        var tab = tabs[t];
        var stepGroup = $(tab.getAttribute("bb:groupId"))
        var img = $(tab.getElementsByTagName('img')[0]);
        var link = $(tab.getElementsByTagName('a')[0]);
        var dataElements = widget.ShowUnsavedChanges.dataElementsByStepGroup[stepGroup.id];
        if ( dataElements == null )
        {
          dataElements = stepGroup.getElementsByTagName('li');
          widget.ShowUnsavedChanges.dataElementsByStepGroup[stepGroup.id] = dataElements;
        }        
        
        var dirtyCount = 0;
        for ( var i = 0; i < dataElements.length; i++ )
        {
          if ( dataElements[i].className.indexOf('dirty') >= 0 )
          {
            dirtyCount++;
          }
        }        
        if ( dirtyCount > 0 && !tab.isDirty)
        {
          img.show();
          link.setStyle({'paddingLeft': '20px'});
          tab.isDirty = true;
        }
        else if ( dirtyCount == 0 && tab.isDirty )
        {
          img.hide();
          link.setStyle({'paddingLeft': ''});
          tab.isDirty = false;
        }
      }
    }
  }
};
// Call this when the value of a hidden data element changes that you want to
// show an indicator for.  Otherwise changing the value of the hidden element directly will
// not cause an indicator to show.
widget.ShowUnsavedChanges.changeHiddenValue = function( hiddenElem, value )
{
  hiddenElem.value = value;
  if ( widget.ShowUnsavedChanges.enabled )
  {
    widget.ShowUnsavedChanges.onValueChange( null, hiddenElem );
  }
};
widget.ShowUnsavedChanges.enabled = false;

widget.ColorPalettePicker = Class.create();
widget.ColorPalettePicker.prototype = 
{
    initialize: function( onChange )
	{
	    widget.ColorPalettePicker.picker = this;
	    
	    this.onChange = onChange;
	    var palettes = [];
	    $A($('paletteLibraryPanel').getElementsByTagName('li')).each( function( li )
	    {
	      if ( page.util.hasClassName( li, 'palette' ) )
	      {
	        palettes.push( $(li) );
	      }
	    });
		this.palettes = palettes;
		this.libraryOpen = false;
		
		this.paletteLibraryPanel = $('paletteLibraryPanel');
		this.paletteLibraryButton = $('paletteLibraryButton');
		
        var updateHandler = this.updateCurrentSelection.bindAsEventListener( this ); 
       // this.paletteLibraryPanel.toggleLibrary();
        if( this.palettes )
        {
        	this.palettes.each( function ( palette )
	        	{
	        		Event.observe( palette, "click", updateHandler );
	        	});
        }
        if( this.paletteLibraryButton )
        {
			Event.observe( this.paletteLibraryButton, "click", this.toggleLibrary.bindAsEventListener( this ) );
		}
 	},
 	
	toggleLibrary: function( )
	{
		if ( this.libraryOpen )
		{
			this.paletteLibraryButton.getElementsByTagName('img')[0].src = "/images/db/p.gif"; // collapse
			this.paletteLibraryPanel.hide();
			this.libraryOpen = false;
		}
		else
		{
			this.paletteLibraryButton.getElementsByTagName('img')[0].src = "/images/db/m.gif"; //expand
			this.paletteLibraryPanel.show();
			this.libraryOpen = true;
		}
 	},
 	
 	
 	selectColorPaletteByExtRef: function( extRef )
 	{
 	  var eventElement = $(extRef);
 	  this.selectColorPaletteByElement( eventElement );
 	},
 	
 	selectColorPaletteByElement: function( eventElement )
 	{
    	this.palettes.each( function ( p )
    	{
			var a = $(p.getElementsByTagName('a')[0]);
			if (a.hasClassName("selected")) a.removeClassName('selected');
    	});
		
		var selPal = eventElement;
		while ( selPal != null && selPal.tagName != 'LI' )
		{
		  selPal = selPal.parentNode;
		  if ( selPal.tagName == 'BODY' )
		  {
		    selPal = null;
		  }
		}
		$(selPal.getElementsByTagName('a')[0]).addClassName('selected');
		widget.ShowUnsavedChanges.changeHiddenValue( $('currentPaletteExtRef'), selPal.id == 'currentsystemthemecolorpalette'? '':selPal.id);
		$('currentPaletteLabel').update( $(selPal.id + '_label').innerHTML );		
		this.copyStyles( selPal.down('.schemePreview'), $('currentPalettePreview') );
		this.copyStyles( selPal.down('.schemePreviewHead'), $('currentPalettePreviewHead') );
		this.copyStyles( selPal.down('.schemePreviewBody'), $('currentPalettePreviewBody') );
		this.copyStyles( selPal.down('.modulePreview'), $('currentModulePalettePreview') );
		this.copyStyles( selPal.down('.modulePreviewHead'), $('currentModulePalettePreviewHead') );
		this.copyStyles( selPal.down('.modulePreviewBody'), $('currentModulePalettePreviewBody') );		
		$('selectedPalette').show();
 	
 	},
	updateCurrentSelection: function( event )
	{
  	var eventElement = Event.element( event );
	  this.selectColorPaletteByElement( eventElement );
		eval( this.onChange );
		Event.stop( event );
	},
	 	
	copyStyles: function( s, d)
	{
	   for (var i in s.style){
	      try{
	         d.style[i] = s.style[i];
	      }
	      catch (e){
	          // do nothing with errors
	      }
	   }
 	}
 	
};
widget.ColorPalettePicker.picker = null;

	
