/* =================================================================================================================================================================== 
* 	Sony Style jcCustomSelect Custom Select box Class
* 	AUTHOR: Jonathan Cheung
* 
*	PRECONDITION:
*		- Prototype.js, Scriptaculous.js (including effects.js)
*		- ss_custom_select.css
* 	OPTIONAL:
*		- Really easy field validation (http://tetlaw.id.au/view/javascript/really-easy-field-validation)
*	
* 	NOTES:
*		- Custom select box done the right way. 	
* 		- This custom select box generates the list from existing Select input and parses it into an UL list
* 		- Custom styles can be applied. (Basic styles are in ss_custom_select'
*	USAGE:
*		- On page load instantiate the custom lise by ID name
* 		new jcCustomSelect(IDNAME, OPTIONS)
*		IDNAME - the ID name of the Selectbox
*		OPTIONS - A JSON Object of the parameters 
*				(currently you can only pass 'formValidation' - the instance of the 'Really easy field validation')
*		e.g. var stateSelect = new jcCustomSelect('state', {formValidation:registrationFormValidation});
* 			
* ===================================================================================================================================================================
*/

var jcCustomSelect = Class.create({
	
	//Class Constructor
	initialize: function(idName, options){
		this.options = Object.extend({
			formValidation: false
		
		}, options || {});
		
		this.idName = idName;
		var element = $(idName)
		var newDiv = document.createElement('A')
		
		var newInput  = document.createElement('INPUT');
		var newSelect = document.createElement('UL');
		
		newSelect.id = element.id+"-jcCustomSelectList"
							
		//Function to transfer all Attirbute to the new UL list
		var elementAttributes = $A($(element).attributes);

		this.parseAttributeTo(element, newDiv)
	

		
		var selectedText = element.options[element.selectedIndex].innerHTML;
		var selectedValue = element.options[element.selectedIndex].value;
		
		for (var i in element.childNodes){
			var thisElement = element.childNodes[i];
			if (thisElement.nodeType == 1){
				
				var newOption = document.createElement('LI');
				
				var newHREF = document.createElement('A');
				newHREF.href = "#";
				newHREF.innerHTML = thisElement.innerHTML
				
				newOption.appendChild(newHREF);

				//Function to transfer all Attirbute to the new LI list
				this.parseAttributeTo(thisElement, newOption);
				
				//Appending click/rollover/rollout action
				Event.observe($(newHREF), 'click', this.onClickOptionHREF.bind(this))
				Event.observe($(newHREF), 'mouseover', this.onOverOptionHREF.bind(this))
				Event.observe($(newHREF), 'mouseout', this.onOutOptionHREF.bind(this))

				$(newSelect).addClassName('NotActive')
				$(newSelect).addClassName('jcCustomSelectList');
				newSelect.appendChild(newOption);
			}
		}
		
		// Select the input the selected value
		$(newDiv).innerHTML =selectedText;
		$(newDiv).rel = selectedValue;
		
		$(newDiv).addClassName('jcCustom');
		$(newSelect).addClassName('jcCustom');
		
		// KRANZ - This is for making the border appear right
		$(newDiv).addClassName('NotActive');
		// End KRANZ
		
		//Initialize the input value
		newInput.id = newDiv.id+"-jcCustom";
		newInput.value = newDiv.rel;
		newInput.type="hidden";
		$(newInput).addClassName('required');
		//Used in Validation.js to do special styling
		$(newInput).addClassName('jcCustom');
		
		element.parentNode.insertBefore(newInput,element);
		element.parentNode.insertBefore(newSelect,newInput);
		element.parentNode.insertBefore(newDiv,newSelect);
		
		//Remove the element.
		element.parentNode.removeChild(element);
		
		//append the select box
		Event.observe($(newDiv), 'click', this.onClickSelect.bind(this));
		Event.observe($(newDiv), 'mouseover', this.onOverSelect.bind(this));
		Event.observe($(newDiv), 'mouseout', this.onOutSelect.bind(this));
		Event.observe($(newSelect), 'mouseout', this.onOutList.bind(this))
		
		// easy accessors // KRANZ
		this.select = $(this.idName + '-jcCustomSelectList');
		this.view = $(this.idName);
		// END KRANZ
		
	},

	// DOM Level 2 events for the new Select 
	onClickSelect: function(e){
		var thisElement = Event.element(e);
		thisElement.next().toggleClassName('NotActive');
		this.view.toggleClassName('NotActive');
		Event.stop(e);
	},
	
	onOverSelect: function (e){
		var thisElement = Event.element(e);
	},
	onOutSelect: function (e){
		var thisElement = Event.element(e);
	},
	
	// DOM Level 2 events for the new List
	onOutList: function(e){
		var thisElement = Event.element(e).parentNode;
		if (Position.within(thisElement, Event.pointerX(e), Event.pointerY(e))  == false && $(thisElement).hasClassName('jcCustomSelectList')){
			$(thisElement).addClassName('NotActive');
			this.view.toggleClassName('NotActive');
		}
	},

	// DOM Level 2 events for the new list items 
	onClickOptionHREF: function(e){
		var thisElement = Event.element(e).parentNode;
		// Toggle the UL "NotActive" class
		thisElement.parentNode.toggleClassName('NotActive');
		this.view.toggleClassName('NotActive');
		this.optionSelected(thisElement);
		Event.stop(e);
		
		this.onchange();
	},
	onOverOptionHREF: function (e){
		var thisElement = Event.element(e).parentNode;
		$(thisElement).addClassName('rollOver');
	},
	onOutOptionHREF: function (e){
		var thisElement = Event.element(e).parentNode;
		$(thisElement).removeClassName('rollOver');
	},
	
	optionSelected: function (thisElement){
		thisElement.parentNode.previous().innerHTML = Element.select(thisElement,'a')[0].innerHTML;
		
		var newValue = (!$(thisElement).getAttribute('rel') )? '':thisElement.getAttribute('rel');
		thisElement.parentNode.previous().rel = newValue;		
		$(thisElement.parentNode.previous().id+"-jcCustom").value = newValue;

		if (
		(this.options.formValidation !=false && this.options.formValidation != undefined) && 
		((this.options.formValidation.options.immediate) || (this.options.formValidation.options.onSubmitImmediate && this.options.formValidation.calledOnce))
		){
			//Bridging to use Validation.js Prototype
			var useTitles = this.options.formValidation.options.useTitles;
			var callback = this.options.formValidation.options.onElementValidate;
			this.options.formValidation.validate($(thisElement.parentNode.previous().id+"-jcCustom"),{useTitle : useTitles, onElementValidate : callback});
		}
	},
	
	parseAttributeTo: function(element, newElement){
		var attributeList =  $(element).attributes;
		if ($(element).id) $(newElement).id= $(element).id;
		if ($(element).className) $(newElement).className= $(element).className;
		if ($(element).name) $(newElement).name= $(element).name;
		if ($(element).rel) $(newElement).setAttribute('rel', $(element).getAttribute('rel'));
		if ($(element).value) $(newElement).setAttribute('value', $(element).getAttribute('value'));
	}
});


// Added by James Kranz.
var jcCustomSelectDynamic = Class.create(jcCustomSelect, {
	// Redefinitions and new functions.
	initialize: function($super, idName, options) {
		$super(idName, options);
		
		if(this.options.onchange && typeof(this.options.onchange) == 'function') {
			this.onchange = this.options.onchange;
		}
		
		this.defaultText = this.options.defaultText ? this.options.defaultText : '';

	},
	addOption: function(optionData) {
		
		if (optionData['name'] && optionData['value']) {
			
			var newOption = document.createElement('LI');
					
			var newHREF = document.createElement('A');
			newHREF.href = "#";
			newHREF.innerHTML = optionData['name'];
			
			// value stuff
			newOption.setAttribute('rel', optionData['value']);
			
			newOption.appendChild(newHREF);
			
			//Appending click/rollover/rollout action
			Event.observe($(newHREF), 'click', this.onClickOptionHREF.bind(this));
			Event.observe($(newHREF), 'mouseover', this.onOverOptionHREF.bind(this));
			Event.observe($(newHREF), 'mouseout', this.onOutOptionHREF.bind(this));
			
			// Another click action, to simulate onchange
			//Event.observe($(newHREF), 'click', this.onchange.bind(this));

			this.select.appendChild(newOption);
			
			if(this.view.innerHTML=='') {
				this.view.innerHTML = this.defaultText;
			}
		} else {
			alert('Incorrect option data passed.');
		}
	},
	changeOption: function() {},
	removeOption: function() {},
	clearOptions: function() {
		this.view.update();
		this.select.innerHTML = '';
	},
	newOptionsFromArray: function(optionArray) {

		for (var i = 0; i < optionArray.length; i++){
			this.addOption(optionArray[i]);				
		}
	},
	onchange: this.onchange ? this.onchange : function(){}
});