var SelectBoxPair = Class.create();

SelectBoxPair.prototype = {	
	initialize: function( el ){
		this.el = $(el);
		this.btn_group = new Array();
		try{
			var src = this.el.select( '.Src' );
		}
		catch( e ){
			var src = this.el.select( 'Src');
		}
		try{
			var dst = this.el.select( '.Dst' );
		}
		catch( e ){
			var dst = this.el.select( 'Dst');
		}
		try{
			var btns = this.el.select( '.Btn' );
		}
		catch( e ){
			var btns = this.el.select( 'Btn');
		}
		try{
			var optgroups = this.el.getElementsByTagName( 'optgroup' );
		}
		catch( e ){
			var optgroups = null;
			//alert( e.message );
		}
		for( btnc=0; btnc<btns.length; btnc++ ){
			if( btns[btnc].hasClassName( 'Remove' ) ) {
				this.btn_group.push(btns[btnc]);
				Event.observe( btns[btnc], 'click', this.__remove.bind( this, src[0], dst[0], optgroups ) );
			}
			if( btns[btnc].hasClassName( 'Add' ) ) {
				this.btn_group.push(btns[btnc]);
				Event.observe( btns[btnc], 'click', this.__add.bind( this, src[0], dst[0], optgroups ) );
			}
		}
		for(selC=0; selC<src.length; selC++) {
			Event.observe(src[selC], 'dblclick', this.__add.bind( this, src[selC], dst[selC], optgroups ) );
			Event.observe(dst[selC], 'dblclick', this.__remove.bind( this, src[selC], dst[selC], optgroups ) );
		}
		this.__buttonEffect(src[0], dst[0]);
	},
	__move: function( srcEl, dstEl ){
		srcOptions = srcEl.options;
		dstOptions = dstEl.options;
		for( move_loop=0; move_loop<srcOptions.length; move_loop++ ){
			if( srcOptions[move_loop].selected ){
				try{
					dstOptions[dstOptions.length] = new Option( srcOptions[move_loop].text, srcOptions[move_loop].value );
					break;
				}catch( e ){
					//alert( e.message );
				}
				move_loop--;
			}
		}
	},
	__buttonEffect: function(srcEl, dstEl){
		var srcOptions = srcEl.options;
		var dstOptions = dstEl.options;
		if(dstOptions.length > 0){
			try{
				this.btn_group[1].removeClassName('Remove_Inactive');
			}catch(e){
				//alert( e.message );
			}
		}else{
			try{
				this.btn_group[1].addClassName('Remove_Inactive');
			}catch(e){
				//alert( e.message );
			}
		}
		if(srcOptions.length > 0){
			try{
				this.btn_group[0].removeClassName('Add_Inactive');
			}catch(e){
				//alert( e.message );
			}
		}else{
			try{
				this.btn_group[0].addClassName('Add_Inactive');
			}catch(e){
				//alert( e.message );
			}
		}
	},
	__add: function( srcEl, dstEl, optgroups ){
		var srcOptions = srcEl.options;
		var dstOptions = dstEl.options;
		var valExist = false;
		var selection = new Array();
		var optc;
		for( optc=0; optc<srcOptions.length; optc++ ){
			if( srcOptions[optc].selected ){
				selection.push(optc);
				if (srcOptions[optc].text.length > 0) {
					try{
						var tempOption = new Option( srcOptions[optc].text, srcOptions[optc].value );
						tempOption.selected = true;
						this.__addOption(tempOption, dstEl, optgroups);
						
					}catch( e ){
						//alert( e.message );
					}
				}
			}
		}
		var num_removed = 0;
		for (var m=0; m<selection.length; m++) {
			//alert('remove ' + srcEl.options[selection[m] - num_removed].text);
			srcEl.remove(selection[ m ]- num_removed);
			num_removed++;
		}
		this.__buttonEffect(srcEl, dstEl);
	},
	__remove: function( srcEl, dstEl, optgroups ){
		var srcOptions = srcEl.options;
		var dstOptions = dstEl.options;
		var dstOptionsRemove = new Array();
		var selection = new Array();
		var num = 0;
		
		for (var remove_loop=0; remove_loop<dstOptions.length; remove_loop++ ) {
			if ( dstOptions[remove_loop].selected ) {
				selection.push(remove_loop);
				num++;
			}
		}
		
		for (var adding_loop_index=0;  adding_loop_index<num;  adding_loop_index++ ) {
			if (dstOptions[adding_loop_index].text.length > 0) {
				try{
					var tempOption = new Option( 
						dstOptions[selection[ adding_loop_index ]].text, 
						dstOptions[selection[ adding_loop_index ]].value );
					tempOption.selected = true;
					this.__addOption(tempOption, srcEl, optgroups);
				} catch( e ){
					//alert( e.message );
				}
			}
		}
		
		
		var num_removed = 0;
		for (var m=0; m<selection.length; m++) {
			//alert('remove ' + dstEl.options[selection[m] - num_removed].text);
			dstEl.remove(selection[ m ]- num_removed);
			num_removed++;
		}
		
		this.__buttonEffect(srcEl, dstEl);
	},
	__addOption: function(opt, eleSelect, optgroups) {
		var optgroupsExist = true;
		try {
			optgroups[0].label;
		} catch (e) {
			optgroupsExist = false;
		}
		
		// Handle adding to an optgroup for either staff or realtors
		if (optgroupsExist && eleSelect.className == 'SourceSelect Src') {
			this.__addOptionToOptgroup(opt, eleSelect, optgroups);
		}
		// Handle a select with no optgroups
		else {
			this.__addOptionToSelect(opt, eleSelect);
		}
	},
	__addOptionToSelect: function(opt, eleSelect) {
		var optText = opt.text;
		if (eleSelect.length == 0 ) { //  In cases of adding to empty destination we default to the first position
				eleSelect.options[0] = opt;
		}
		else {			
			//console.debug('len: ' + eleSelect.length);
			for (var add_option_loop=0; add_option_loop<eleSelect.length; add_option_loop++ ) {
				
				// Insert any null value items to the top. ie. All Cities
				if (opt.value.length == 0) {
					var tmpOpt = new Option(opt.text, '');
					try {
						eleSelect.add(tmpOpt,  eleSelect.options[0]);
						break;						
					} catch ( e ) {
						eleSelect.add(tmpOpt, 0);
						break;						
					}
				}
				else {
					var right = eleSelect.options[add_option_loop];
					var rightText = this.__cleanString(right.innerHTML.toLowerCase());
					//alert('[' + opt.text.toLowerCase() + '] : [' + rightText + ']');
					//console.debug('right: ' + rightText);
					if (opt.text.toLowerCase() == rightText) {
						// Skip
						//console.debug('SKIP');
						break;
					}
					
					if ( opt.text.toLowerCase() < rightText ) {
						//console.debug(opt.text.toLowerCase() + ' < ' + rightText);
						
						if (right.value == undefined || right.value == '' || right.value.length == 0) {
							//console.debug('UNDEF');
							
							var offset = 1;
							//if (add_option_loop > 0) {
							//	offset = 0;
							//}
							try {
								eleSelect.add(opt,  eleSelect.options[add_option_loop + offset]);
								break;
							} catch ( e ) {
								eleSelect.add(opt, add_option_loop + offset);
								break;
							}
						}
						else {
							//console.debug('DEF' + rightText);
							try {
								eleSelect.add(opt,  eleSelect.options[add_option_loop]);
							} catch ( e ) {
								eleSelect.add(opt, add_option_loop);
							}
							break;
						}
					}
					else if (add_option_loop == (eleSelect.length - 1)) {
						try {
							eleSelect.add(opt,  eleSelect.options[add_option_loop + 1]);
						} catch ( e ) {
							eleSelect.add(opt, add_option_loop + 1);
						}
						break;
					}
				}
			}
		}
	},
	__addOptionToOptgroup: function(opt, eleSelect, optgroups) {	
		var optText = opt.text;
		if (opt.value.substring(0,6) == 'staff_') {
			
			// Clean the optgroups of any dead children
			for (var q=0; q<optgroups[1].childNodes.length; q++) {
				var t = optgroups[1].childNodes[q];
				
				if (t.text==undefined) {
					optgroups[1].removeChild(t);
				}
			}
			
			if (optgroups[1].childNodes.length == 0) {
				optgroups[1].appendChild(opt);
		    	optgroups[1].childNodes[0].innerHTML = optText;
			}
			else {
				for (var add_og_loop=0; add_og_loop<optgroups[1].childNodes.length; add_og_loop++ ) {
					//console.debug(add_og_loop + ' : ' + optgroups[1].childNodes.length);
					try {
						//console.debug(optgroups[0].childNodes[add_og_loop].text.toLowerCase());
						if ( opt.text.toLowerCase() < optgroups[1].childNodes[add_og_loop].text.toLowerCase() ) {
					    	optgroups[1].insertBefore(opt, optgroups[1].childNodes[add_og_loop]);
							// Reassign the text since IE vomits all over itself otherwise
					    	optgroups[1].childNodes[add_og_loop].innerHTML = optText;
					    	break;
						}
						else if (add_og_loop == (optgroups[1].childNodes.length - 1)) {
							optgroups[1].appendChild(opt);
					    	optgroups[1].childNodes[add_og_loop + 1].innerHTML = optText;
							break;
						}
					} catch ( e ) {
						//console.debug('FOUND UNDEF AT ' + add_og_loop);
						if (add_og_loop == (optgroups[1].childNodes.length - 1)) {
							//console.debug('APPENDING ' + optText);
							optgroups[1].appendChild(opt);
					    	optgroups[1].childNodes[add_og_loop].innerHTML = optText;
							break;
						}
					}
				}
			}
		}
		else if (opt.value.substring(0,8) == 'realtor_') {
			
			// Clean the optgroups of dead children
			for (var q=0; q<optgroups[0].childNodes.length; q++) {
				var t = optgroups[0].childNodes[q];
				
				if (t.text==undefined) {
					optgroups[0].removeChild(t);
				}
			}
			
			if (optgroups[0].childNodes.length == 0) {
				optgroups[0].appendChild(opt);
		    	optgroups[0].childNodes[0].innerHTML = optText;
			}
			else {
				for (var add_og_loop=0; add_og_loop<optgroups[0].childNodes.length; add_og_loop++ ) {
					try {
						//console.debug(add_og_loop);
						//console.debug(optgroups[0].childNodes[add_og_loop].text.toLowerCase());
						if ( opt.text.toLowerCase() < optgroups[0].childNodes[add_og_loop].text.toLowerCase() ) {
					    	optgroups[0].insertBefore(opt, optgroups[0].childNodes[add_og_loop]);
					    	optgroups[0].childNodes[add_og_loop].innerHTML = optText;
					    	//console.debug(optgroups[0].childNodes[add_og_loop].text);
					    	break;
						}
						else if (add_og_loop == (optgroups[0].childNodes.length - 1)) {
							optgroups[0].appendChild(opt);
					    	optgroups[0].childNodes[add_og_loop + 1].innerHTML = optText;
							break;
						}
					} catch ( e ) {
						//console.debug('FOUND UNDEF AT ' + add_og_loop);
						if (add_og_loop == (optgroups[0].childNodes.length - 1)) {
							//console.debug('APPENDING ' + optText);
							optgroups[0].appendChild(opt);
					    	optgroups[0].childNodes[add_og_loop].innerHTML = optText;
							break;
						}
					}
				}
			}
		}
	},
	__cleanString: function(s) {
		var str = s;
		while(str.indexOf("\r") >= 0 || str.indexOf("\n") >= 0
			 || str.indexOf("\t") >= 0) {
			str = str.replace(/(\r)|(\n)|(\t)/g, ""); 
		}
		return str;
	}
}

SelectBoxPair.SelectAllDst = function() {
	try{
		var els = this.el.select( '.Dst' );
	}
	catch( e ){
		var els = $$( '.Dst' );
	}
	for( elsc=0; elsc<els.length; elsc++ ) {
	dstOptions = els[elsc].options;
		for ( select_all_loop=0; select_all_loop<dstOptions.length; select_all_loop++ ) {
			dstOptions[select_all_loop].selected = true;
		}
	}
}

SelectBoxPair.InitPage = function(){
	var els = $$('.SelectBoxPair');
	for( sbpc=0; sbpc<els.length; sbpc++ )
		new SelectBoxPair( els[sbpc] );
}
Event.observe( window, 'load', SelectBoxPair.InitPage );
