var Form = new Class( {
	initialize: function( o, a ) {
		if( ! $defined( o.method ) ) { o.method = 'post'; }
		if( o.method != 'post' && o.method != 'get' ) {
			a.unshift( [ 'hidden', { name: '_method', value: o.method } ] );
			o.method = 'post';
		}
		return new Element( 'form', o ).adopt( this.fields( a ) );
	},
	capEach: function( s ) {
		return s.replace( /([A-Z])/g, " $1" ).capitalize();
	},
	fields: function( a ) {
		return new Element( 'ul', {
			'class': 'fields'
		} ).adopt( a.map( this.field.bind( this ) ) );
	},
	field: function( a ) {
		var t = a.shift(), o = a.shift();
		if( o.id === undefined ) { o.id = o.name; }
		switch( t ) {
			case 'radio':
				f = this.radio( t, o );
				break;
			case 'checkbox':
				f = this.radio( t, o );
				break;
			case 'textarea':
				f = this.textarea( o );
				break;
			case 'select':
				f = this.select( o );
				break;
			default:
				f = this.input( t, o );
				break;
		}
		if( t != 'hidden' ) {
			return new Element( 'li', {
				'class': 'field'
			} ).adopt( f );
		} else {
			return f;
		}
	},
	label: function( o ) {
		var l = ( o.label ) ? o.label : this.capEach( o.name );
		delete o.label;
		return new Element( 'label', {
			'for': o.id,
			html: l
		} );
	},
	input: function( t, o ) {
		var a = [];
		if( t != 'hidden' && t != 'button' && t != 'submit' ) {
			a.push( this.label( o ) );
		}
		if( t == 'text' ) { o['class'] = 'text'; }
		else if(
			( t == 'button' || t == 'submit' ) &&
			( o.name !== undefined && o.value === undefined )
		) { o.value = this.capEach( o.name ); }
		a.push( new Element( 'input', $merge( o, { type: t } ) ) );
		return a;
	},
	textarea: function( o ) {
		return [
			this.label( o ),
			new Element( 'textarea', o )
		];
	},
	select: function( o ) {
		var options = o.options, value = o.value;
		delete o.options;
		delete o.value;
		var m = function( s ) {
			var o = { value: s, html: this.capEach( s ) };
			if( s == value ) { o.selected = 'selected'; }
			return new Element( 'option', o );
		};
		return [
			this.label( o ),
			new Element( 'select', o ).adopt( options.map( m.bind( this ) ) )
		];
	},
	radio: function( t, o ) {
		var options = o.options, value = o.value;
		delete o.options;
		delete o.value;
		var a = [];
		for( var i = 0; i < options.length; i++ ) {
			var w = $merge( o, {
				type: t,
				value: options[i],
				name: ( t == 'radio' ) ? o.name : o.name+'[]',
				id: o.id+i
			} );
			if(
				( t == 'radio' && value == w.value ) ||
				value.contains( w.value )
			) { w.checked = 'checked'; }
			a.push( new Element( 'li' ).adopt(
				new Element( 'input', w ),
				this.label(
					$merge( o, {
						label: this.capEach( w.value ),
						id: w.id
					} )
				)
			) );
		}
		return [
			this.label( o ),
			new Element( 'ul', { children: a } )
		];
	}
} );