/*
 * Copyright 2006, John Drinkwater <john@nextraweb.com>
 * Distributed under the terms of the MIT License.
 * Please note, this script isn't as DOM friendly as I would like, 
 * but IE, as always, has problems with <select> and <option>s
 */

function addEvent( object, type, handler ) {
	if ( object.addEventListener ) {
		object.addEventListener( type, handler, false );
	} else if ( object.attachEvent ) {
		object.attachEvent( [ 'on', type ].join( '' ),handler );
	} else {
		object[ [ 'on', type ].join( '' ) ] = handler;
	}
}

// From Prototype
function $( ) {
    var elements = new Array( );
    for ( var i = 0; i < arguments.length; i++ ) {
        var element = arguments[ i ];
        if ( typeof element == 'string' )
            element = document.getElementById( element );
        if ( arguments.length == 1 )
            return element;
        elements.push( element );
    }
    return elements;
}

/*
	The user has changed the selected component
 */
function selectComponent( e ) {

	// because IE has never made it easy..
	var caller;
	if ( !e ) var e = window.event;
	if ( e.target ) caller = e.target; else if ( e.srcElement ) caller = e.srcElement;
	if ( caller.nodeType == 3 ) // defeat Safari bug
		caller = caller.parentNode;
	var level = caller.stage; 

	// take the current selection, and make a haiku/component
	var text, component = '';
	for ( var i = 1; i < level + 1 ; i++ ) {
		text = selector[ i ].options[ selector[ i ].selectedIndex ].text;
		if ( text != '' )
			component += text + '/';
	}
	hiddenField.value = component.substring( 0, component.length - 1 );

	// bomb out if this is a last choice
	if ( level >= maxBranches )
		return;

	// remove any <select>s to the right of us
	var remover, i;
	for ( i = maxBranches; i > level; i-- ) {
		if ( null != ( remover = selector[ i ] ) ) {
			if ( remover.parentNode )
				 remover.parentNode.removeChild( remover );
		}
	}

	// check if the user back–pedalled to a non option
	var parentChoice = selector[ level ].options[ selector[ level ].selectedIndex ].text;
	if ( parentChoice == '' )
		return;

	var currentSelector = selector[ level + 1 ];

	var subChoice, superChoice, previous = '';
	currentSelector.options.length = 0; // thanks ppk, empty the <select> of <option>s
	currentSelector.options[ 0 ] = new Option( '', '' );

	var i;
	for ( i = 0, p = 1; i < componentList.length ; i++ ) {
		subChoice = componentList[ i ][ level ]; 
		superChoice = componentList[ i ][ level - 1 ]; 
		if ( previous != subChoice && subChoice != null && superChoice == parentChoice ) {
			previous = subChoice;
			currentSelector.options[ p++ ] = new Option( subChoice, subChoice );
		}
	}
	// avoid cases where there are no options, ie, we have selected a leaf
	if ( currentSelector.options.length <= 1 )
		return;

	// We're done, add it back to the page
	var parent = caller.parentNode;
	var sibling = caller.nextSibling;
	if ( sibling != null )
		parent.insertBefore( currentSelector, sibling );
	else
		parent.appendChild( currentSelector );
}

/*
	This function deletes the <select> box, and replaces it with a hidden input box, 
	and a reduced <select> with just the first/ component: this new element has an 
	event that triggers on change, adding further <select> boxes
 */
function reduceComponents( ) {

	// check support, else use non-js method
	if ( !document.createElement )
		return; 

	var original = $( 'component' );
	var parent = original.parentNode;
	window.maxBranches = 0;
	window.componentList = new Array( );

	// split the options
	var i;
	for ( i = 0; i < original.options.length; i++ ) {
		
		componentList[ i ] = original.options[ i ].text.split( '/' );
		maxBranches = ( maxBranches < componentList[ i ].length ? componentList[ i ].length : maxBranches );
	}

	// create some replacement dropdowns
	window.selector = new Array( );
	for ( i = 1; i <= maxBranches; i++ ) {
		selector[ i ] = document.createElement( 'SELECT' );
		selector[ i ].id = 'component-selector-' + i;
		selector[ i ].className = 'haikucomponent';
		selector[ i ].stage = i;
		addEvent( selector[ i ], 'change', selectComponent );
		addEvent( selector[ i ], 'keyup', selectComponent );
	}

	var currentSelector = selector[ 1 ];
	 window.hiddenField = document.createElement( 'INPUT' );
			hiddenField.id = original.id;
			hiddenField.name = original.name;
			hiddenField.type = 'hidden';	

	// populate the choice
	var p, i, previous = null;
	for( i = 0, p = 0; i < componentList.length ; i++ ) {
		if ( previous != componentList[ i ][ 0 ] && componentList[ i ][ 0 ] != null ) {
			previous = componentList[ i ][ 0 ];
			currentSelector.options[ p++ ] = new Option( previous, previous );
		}
	}
	parent.replaceChild( currentSelector, original );
	parent.insertBefore( hiddenField, currentSelector );

	// For <select>s without a 'null' selection, we need to propagate sub—choices
	currentSelector.selectedIndex = 0;
	var event = { target : currentSelector };
	selectComponent( event );
}

addEvent( window, 'load', reduceComponents );

