// Prototype Extensions - Select
// Version:               0.1
// Depends on:            Prototype 1.5.0, Browser Detect 2.1.6
// Documentation:         http://rafael.adm.br/prototype-extensions
// License:               http://creativecommons.org/licenses/by/2.5/
// Author:                Rafael Lima (http://rafael.adm.br)
// Contributors:          Wagner Rodrigues

var Select = {

  getOptions: function(element) {
	//return $(element).childElements();
	return $(element).options;
  },

  getSelectedOptions: function(element) {
	for(i=0;i<$(element).options.length;i++){
		if($(element).options[i].selected)
			return $(element).options[i];
	}
  },

  getUnselectedOptions: function(element) {
	return this.getOptions(element).findAll(function(element){ if(!element.selected) return element; });
  },

  // Select first option of one select element
  selectFirst: function (element) {
    $(element).options[0].selected = true;
  },

  // Update text with *new_value* of option with *index* of select *element*
  updateOption: function (element, index, new_value) {
    $(element).options[index].text = new_value;
  },

  // Select all options from select element 
  selectAll: function (element) {
    element = $(element)
	for (i=0, l=element.options.length;i<l;i++) {
        element.options[i].selected = true;
    }
  },

  // Unselect all options from select element
  unselectAll: function (element, ignore_empty) {
    element = $(element);
    for (i=0, l=element.options.length;i<l;i++) {
      element.options[i].selected = false;
	}
  },

  // Select all empty options from select element 
  selectEmpties: function (element) {
    element = $(element)
	for (i=0, l=element.options.length;i<l;i++) {
      if ('' == element.options[i].value)
	    element.options[i].selected = true;
    }
  },

  // Unselect all empty options from select element
  unselectEmpties: function (element, ignore_empty) {
    element = $(element);
    for (i=0, l=element.options.length;i<l;i++) {
      if ('' == element.options[i].value)
		element.options[i].selected = false;
	}
  },

  // Select all empty options from select element 
  selectNonEmpties: function (element) {
    element = $(element)
	for (i=0, l=element.options.length;i<l;i++) {
      if ('' != element.options[i].value)
	    element.options[i].selected = true;
    }
  },

  // Unselect all empty options from select element
  unselectNonEmpties: function (element, ignore_empty) {
    element = $(element);
    for (i=0, l=element.options.length;i<l;i++) {
      if ('' != element.options[i].value)
		element.options[i].selected = false;
	}
  },

  selectOption: function (element, value){
	element = $(element);
	for (i=0, l=element.options.length;i<l;i++) {
      if (value == element.options[i].value){
		element.options[i].selected = true;
		return true;
	  }
	}
	return false;
  },

  //  Add an option to a select or optgroup
  addOption: function(element, text, value, selected) {
	if (null == selected) selected = true;
	option_element = new Option(text, value, false, selected);
	if (Browser.isIE) option_element.innerHTML = text;
	$(element).appendChild(option_element);
  },
  
  //  Add an option to a select or optgroup from input object
  addOptionFromInput: function(select_element, input_element, selected) {
    select_element = $(select_element);
	input_element = $(input_element);
	if (input_element.value == "") return;
    self.addOption(select_element,input_element.value,input_element.value, selected);
  },
  
  //  Add an optgroup to a select
  addGroup: function (select_element,label,id,allow_duplicates) {
    select_element = $(select_element);
	if (null == allow_duplicates) allow_duplicates = false
    if (false == allow_duplicates) {
      for (gi=0, gl=select_element.childNodes.length;gi<gl;gi++) {
        if ('optgroup' == select_element.childNodes[gi].nodeName.toLowerCase() && label == select_element.childNodes[gi].label) {
          return select_element.childNodes[gi];
        }
      }
    }
	var group_element = document.createElement('optgroup');
	group_element.label = label;
	group_element.id = id;
	select_element.appendChild(group_element);
	return group_element;
  },

  //  Delete an option from a select
  deleteOption: function (select_element,index,remove_optgroup) {
    select_element = $(select_element);
	if (null != index) {
      select_element.options[index] = null;
      if(!Browser.isIE5x && remove_optgroup) {
        cont_children_nodes=0;
        for (i=0, l=parent_node.childNodes.length;i<l;i++) {
          if ('option' == parent_node.childNodes[i].nodeName.toLowerCase())
            cont_children_nodes++;
        }
        if (null != parent_node && 'optgroup' == parent_node.nodeName.toLowerCase() && 0 == cont_children_nodes) {
          select_element.removeChild(parent_node);
          parent_node = null;
		}
      }
    }
    if ('undefined' != select_element.options[index] && null != select_element.options[index])
      select_element.options[index].selected = true;
  },

  //  Delete all options from a select
  //  If ignore_empty is true it will not dele options with empty value
  deleteAll: function (select_element, ignore_empty) {
    select_element = $(select_element);
    for (var i=select_element.options.length-1;i>-1;i--) {
      if (!ignore_empty || select_element.options[i].value != '')
        this.deleteOption(select_element, i);
    }
  },

  //  Delete all selected options from a select.
  //  If ignore_empty is true it will not dele options with empty value
  deleteSelected: function (select_element, ignore_empty) {
    select_element = $(select_element);
    for (var i=select_element.options.length-1;i>-1;i--) {
      if (select_element.options[i].selected && (!ignore_empty || select_element.options[i].value != ''))
        this.deleteOption(select_element, i);
    }
  },

  //  Copy all selected options from one select object to another creating the optgroups if necessary
  copySelected: function (from_element, to_element, ignore_empty) {
    from_element = $(from_element);
	to_element = $(to_element);
    for (i=0, l=from_element.options.length;i<l;i++) {
      if (true == from_element.options[i].selected && from_element.options[i].value != '') {
        if ('select' == from_element.options[i].parentNode.nodeName.toLowerCase())
          this.addOption(to_element,from_element.options[i].text,from_element.options[i].value);
        else if ('optgroup' == from_element.options[i].parentNode.nodeName.toLowerCase()) {
          group_element = this.addGroup(to_element,from_element.options[i].parentNode.label,from_element.options[i].parentNode.id+'to');
          if (Browser.isOpera)
            this.addOption(to_element,from_element.options[i].text,from_element.options[i].value);
          else
            this.addOption(group_element,from_element.options[i].text,from_element.options[i].value);
        }
      }
    }
  },

  //  Copy all options from one select object to another creating the optgroups if necessary
  copyAll: function (from_element,to_element) {
    from_element = $(from_element);
	to_element = $(to_element);
    this.selectAll(from_element);
    this.copySelected(from_element,to_element);
  },

  //  Copy selected options from one select object to another creating the optgroups if necessary
  moveSelected: function (from_element,to_element) {
    from_element = $(from_element);
	to_element = $(to_element);
    this.copySelected(from_element, to_element);
	this.deleteSelected(from_element);
  },

  //  Copy all options from one select object to another creating the optgroups if necessary
  moveAll: function (from_element,to_element) {
    from_element = $(from_element);
	to_element = $(to_element);
    this.copyAll(from_element, to_element);
	this.deleteAll(from_element);
  },

  // Serialize select values and populate input element
  serializeAllTo: function (select_element, to_element, delimiter, ignore_empty) {
    select_element = $(select_element);
	to_element = $(to_element);

    joinned = '';
    for (i=0, l=select_element.options.length;i<l;i++) {
      if (!ignore_empty || select_element.options[i].value != '') {
        joinned = joinned+select_element.options[i].value;
        if (i != l-1)
          joinned = joinned+delimiter;
      }
    }
    to_element.value = joinned;
  },
  
  serializeSelectedTo: function (select_element, to_element, delimiter, ignore_empty) {
    select_element = $(select_element);
	to_element = $(to_element);

    joinned = '';
    for (i=0, l=select_element.options.length;i<l;i++) {
      if (!ignore_empty || select_element.options[i].value != '') {
        if(select_element.options[i].selected){
			joinned = joinned+select_element.options[i].value;
	        if (i != l-1)
	          joinned = joinned+delimiter;
		}
      }
    }
    to_element.value = joinned;
  }
};

function Assoc(){
	function add(){
		elementArray = new Array();
		this.notAssoc = this.form.notassoc;
		this.assoc = this.form.assoc;
		i=0;
		while(this.notAssoc.selectedIndex != -1){
			if(this.notAssoc.options[i].selected){
				elementArray.push(this.notAssoc.options[i]);
				this.notAssoc.options[i].selected = false;
			}
		i++;
		}
		
		for(i=0;i<elementArray.length;i++){
			this.element = document.createElement('option');
			this.element.text = elementArray[i].text;
			this.element.value = elementArray[i].value;
			try{
				this.assoc.add(this.element);
			}
			catch(ex){
				this.assoc.add(this.element,null);
			}
			
		}
		
		for(i=0;i<elementArray.length;i++){
			this.notAssoc.remove(elementArray[i].index);
		}
		
	}
	
	function remove(){
		elementArray = new Array();
		this.assoc = this.form.assoc;
		this.notAssoc = this.form.notassoc;
		i=0;
		while(this.assoc.selectedIndex != -1){
			if(this.assoc.options[i].selected){
				elementArray.push(this.assoc.options[i]);
				this.assoc.options[i].selected = false;
			}
		i++;
		}
		
		for(i=0;i<elementArray.length;i++){
			this.element = document.createElement('option');
			this.element.text = elementArray[i].text;
			this.element.value = elementArray[i].value;
			try{
				this.notAssoc.add(this.element);
			}
			catch(ex){
				this.notAssoc.add(this.element,null);
			}
			
		}
		
		for(i=0;i<elementArray.length;i++){
			this.assoc.remove(elementArray[i].index);
		}
	}

	function addAll(){
		elementArray = new Array();
		this.notAssoc = this.form.notassoc;
		this.assoc = this.form.assoc;
		for(i=0;i<this.notAssoc.length;i++){
			elementArray.push(this.notAssoc.options[i]);
		}
		
		for(i=0;i<elementArray.length;i++){
			this.element = document.createElement('option');
			this.element.text = elementArray[i].text;
			this.element.value = elementArray[i].value;
			try{
				this.assoc.add(this.element);
			}
			catch(ex){
				this.assoc.add(this.element,null);
			}
			
		}
		
		for(i=0;i<elementArray.length;i++){
			this.notAssoc.remove(elementArray[i].index);
		}
		
	}
	
	function removeAll(){
		elementArray = new Array();
		this.notAssoc = this.form.notassoc;
		this.assoc = this.form.assoc;
		for(i=0;i<this.assoc.length;i++){
			elementArray.push(this.assoc.options[i]);
		}
		
		for(i=0;i<elementArray.length;i++){
			this.element = document.createElement('option');
			this.element.text = elementArray[i].text;
			this.element.value = elementArray[i].value;
			try{
				this.notAssoc.add(this.element);
			}
			catch(ex){
				this.notAssoc.add(this.element,null);
			}
			
		}
		
		for(i=0;i<elementArray.length;i++){
			this.assoc.remove(elementArray[i].index);
		}
	}
	
	this.add = add;
	this.remove = remove;
	this.addAll = addAll;
	this.removeAll = removeAll;
}

