/**
* EditableToggleField
*
* A HTML field which can be toggled between displaying the HTML content and displaying the same HTML content in an editing window.
*
* @param field_content: The DOM element used as the content of the field
* @param submit_command: The unbuilt command name to be used by the submit button
* @param content_field_name: The name of the content field which will be used when content is passed to the AJAX command
* @param refresh_command: The fully built refresh command
* @param w: The width of the field
* @param style_set: Supports the following styles
* @param widget_factory: The unbuilt widget factory to use when creating the widget
* @param refreshable: boolean to determine whether or not to create a refresh button if editability is false.  If editability is true, always create 
*                     the refresh button.
* @param editability: boolean to determine whether or not to create the editing functions
* @param type: The type of the field.
*              Currently supported values:
*                -WYSIWYG
*                -Text
*                -Selection
**/
function EditableToggleField (
	field_content ,
	submit_command ,
	content_field_name ,
	refresh_command ,
	w ,
	style_set ,
	widget_factory ,
	refreshable ,
	editability ,
	type ,
	value_population_command
	) { 

	this.editability = editability;
	this.refresh_command = refresh_command;
	this.submit_command = submit_command;
	this.type = type;
	this.style_set = style_set;
	this.edit_value_population_command = value_population_command;

	//generate the toggle field widget
	this.field_widget = new widget_factory( this.style_set ).build();

	//force the width of the toggle field if necessary
	if ( w && w!= null )
		this.field_widget.setWidgetWidth( w );

	//create the normal display field
	this.toggleable_field = document.createElement( 'div' );
	this.toggleable_field.appendChild( field_content );
	
	this.field_widget.addContentNode( this.toggleable_field );

	//create a widget engine to house our buttons
	this.widget_engine = new TabularWidgetLayoutFactory( this.style_set, 10 ).build();

	//add the widget engine to the toggle_field
	this.field_widget.addContentNode( this.widget_engine.getDOM() );

	//create a refresh button if refresh is true or editability is true
	if ( refreshable || editability ) { 
		this.refresh_button = new REFRESHButtonFactory( this, this.style_set, null ).build();
		this.widget_engine.addWidget( this.refresh_button );
	}

	//create editing fields if editability is turned on
	if ( editability ) { 

		this.edit_button = new window[ this.type + "EDITButtonFactory" ]( this, this.style_set ).build();
		this.cancel_button = new window[ this.type + "CANCELButtonFactory" ]( this, this.style_set ).build();
		this.submit_button = new window[ this.type + "SUBMITButtonFactory" ]( this, this.style_set, submit_command ).build();

		this.widget_engine.addWidget( this.edit_button );
		this.widget_engine.addWidget( this.cancel_button );
		this.widget_engine.addWidget( this.submit_button );

		//init the cancel and submit button to hidden
		this.cancel_button.hideWidget();
		this.submit_button.hideWidget();

	}

	//create the status widget
	this.status_widget = new StatusWidget( "status" );
	this.widget_engine.addWidget( this.status_widget );

	//set the unrendered content
	this.unrendered_content = field_content.innerHTML;

	//set the rendered content
	this.rendered_content = field_content;

}

//new EditableToggleField( document.createElement( 'div' ) );

/**
* EditableToggleField.getDOM
*
* @returns the DOM representation of the toggle field
**/
EditableToggleField.prototype.getDOM = function() { 
	return this.field_widget.getWidgetDOM();
}

/**
* EditableToggleField.setButtonConfigurationToEdit
**/
EditableToggleField.prototype.setButtonConfigurationToEdit = function() {

	if ( this.editability == true ) { 
		this.edit_button.hideWidget();
		this.cancel_button.showWidget();
		this.submit_button.showWidget();
	}

}

/**
* EditableToggleField.setButtonConfigurationToDefault
**/
EditableToggleField.prototype.setButtonConfigurationToDefault = function() { 

	if ( this.editability == true ) { 
		//make the cancel button and the submit button hidden
		this.cancel_button.hideWidget();
		this.submit_button.hideWidget();

		//make the edit button visible
		this.edit_button.showWidget();
	}

}

/**
* EditableToggleField.toggleContent
*
* Replaces the contents of the toggleable_field area with the passed in contents
*
* @param c: The passed in contents
**/
EditableToggleField.prototype.toggleContent = function( c ) { 

	removeAllChildren( this.toggleable_field );
	this.toggleable_field.appendChild( c );

}

/**
* EditableToggleField.unToggleContent
*
* Changes the contents of the toggleable_field to the original contents
*
**/
EditableToggleField.prototype.unToggleContent = function() { 

	removeAllChildren( this.toggleable_field );
	this.toggleable_field.appendChild( this.rendered_content );

}

/**
* EditableToggleField.swapContent
*
* Swap passed in content for the current content
*
* @param c The new content
**/
EditableToggleField.prototype.swapContent = function( c ) {

	//set the unrendered content
	this.unrendered_content = c.innerHTML;

	//set the rendered content
	this.rendered_content = c;

	removeAllChildren( this.toggleable_field );

	this.toggleable_field.appendChild( this.rendered_content );

	this.setButtonConfigurationToDefault();

	return true;

}

/**
* EditableToggleField.setStatusToWorking
*
* Populates the status_field with a working animation and a message passed in
*
* @param msg
**/
EditableToggleField.prototype.setStatusToWorking = function ( msg ) { 

	this.status_widget.setStatus( "working", msg );

}

/**
* EditableToggleField.setStatusFailed
*
* Populates the status_field with a failed x and a message
*
* @param msg
**/
EditableToggleField.prototype.setStatusFailed = function ( msg ) { 

	this.status_widget.setStatus( "failure", msg );

}

/**
* EditableToggleField.clearStatus
*
* Clears the status field
*
**/
EditableToggleField.prototype.clearStatus = function() { 

	this.status_widget.hideWidget();

}

/**
* EditableToggleField.setRefreshCommand
*
* @param c The refresh command
*
**/
EditableToggleField.prototype.setRefreshCommand = function( c ) { 
	if ( this.refresh_button ) {
		this.refresh_command = c;
		this.refresh_button.setCommand( c );
		return true;
	}
	return false;
}

/**
* EditableToggleField.setSubmitCommand
*
* @param c The refresh command
*
**/
EditableToggleField.prototype.setSubmitCommand = function( c ) { 
	if( this.submit_button ) {
		this.submit_button.setCommand( c );
		return true;
	}
	return false;
}

/**
* REFRESHButtonFactory
*
* Generate the REFRESH button
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
* @param refresh_command: The command to execute upon refresh request
**/
function REFRESHButtonFactory( f, style_set, refresh_command ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
	this.refresh_command = refresh_command;
}

new REFRESHButtonFactory();

REFRESHButtonFactory.prototype.build = function() { 

	var rbut = new SimpleButtonWidget( this.style_set, this.refresh_command );
	
	rbut.addContentNode( textToDOM( "span", "REFRESH" ) );

	return rbut;

}

/**
* WYSIWYGEDITButtonFactory
*
* Generate a button which will turn a WYSIWYG editor on and off within the EditableToggleField 
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
**/
function WYSIWYGEDITButtonFactory( f, style_set ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
}

new WYSIWYGEDITButtonFactory();

WYSIWYGEDITButtonFactory.prototype.build = function() { 

	var rbut = new SimpleButtonWidget( this.style_set, new SwitchToWYSIWYGEditCommand( this.editable_toggle_field ) );
	
	rbut.addContentNode( textToDOM( "span", "EDIT" ) );

	return rbut;

}

/**
* SwitchToWYSIWYGEditCommand
*
* The command which will build the WYSIWYG editor and populate the EditableToggleField 
*
* @param f: The editable toggle field
**/
function SwitchToWYSIWYGEditCommand( f ) { 

	this.associated_EditableToggleField = f;

}

new SwitchToWYSIWYGEditCommand();

SwitchToWYSIWYGEditCommand.prototype.execute = function () { 

	var wysiwyg_height = parseInt( this.associated_EditableToggleField.toggleable_field.offsetHeight ) + 25;
	if ( parseInt( wysiwyg_height ) > parseInt( getWindowHeight() ) ) { 
		if ( parseInt( getWindowHeight() ) < 200 ) { 
			wysiwyg_height = 600;
		}
		else {
			wysiwyg_height = parseInt( getWindowHeight() ) - 75;
		}
	}

	//generate the WYSIWYG editor
	var wysiwyg = new WYSIWYGObject(
		wysiwyg_height, 
		parseInt( this.associated_EditableToggleField.toggleable_field.offsetWidth ) - 10 
	);

	//render the WYSIWYG editor
	var rwysiwyg = wysiwyg.render();

	//toggle the field
	this.associated_EditableToggleField.toggleContent( rwysiwyg );

	//set the button configuration
	this.associated_EditableToggleField.setButtonConfigurationToEdit();

	//turn on the editing
	setTimeout( EditingSetupClosure( wysiwyg, this.associated_EditableToggleField.unrendered_content ) , 150 );

	this.associated_EditableToggleField.activeEditor = wysiwyg;

}

/**
* WYSIWYGCANCELButtonFactory
*
* Generate the CANCEL button
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
**/
function WYSIWYGCANCELButtonFactory( f, style_set ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
}

new WYSIWYGCANCELButtonFactory();

WYSIWYGCANCELButtonFactory.prototype.build = function() { 

	var rbut = new SimpleButtonWidget( this.style_set, new CancelWYSIWYGEditCommand( this.editable_toggle_field ) );
	
	rbut.addContentNode( textToDOM( "span", "CANCEL" ) );

	return rbut;

}

/**
* CancelWYSIWYGEditCommand
*
* Remove the WYSIWYG Editor from the Toggle Field and replace it with the original content
*
* @param f: The editable toggle field
**/
function CancelWYSIWYGEditCommand( f ) { 

	this.associated_EditableToggleField = f;

}

new CancelWYSIWYGEditCommand();

CancelWYSIWYGEditCommand.prototype.execute = function () { 

	//toggle the field
	this.associated_EditableToggleField.unToggleContent();

	this.associated_EditableToggleField.setButtonConfigurationToDefault();

	this.associated_EditableToggleField.activeEditor = null;

}

/**
* WYSIWYGSUBMITButtonFactory
*
* Generate the SUBMIT button
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
* @param submit_command: The command to execute upon submit request
**/
function WYSIWYGSUBMITButtonFactory( f, style_set, submit_command ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
	this.submit_command = submit_command;
}

new WYSIWYGSUBMITButtonFactory();

WYSIWYGSUBMITButtonFactory.prototype.build = function() {

	var rbut = new SimpleButtonWidget( this.style_set, this.submit_command );
	
	rbut.addContentNode( textToDOM( "span", "SUBMIT" ) );

	return rbut;

}

/**
* TestSubmitWYSIWYGEditCommand
*
* Generate a submit command and execute it
**/
function TestSubmitWYSIWYGEditCommand( f, submit_command, submit_request_object ) { 

	this.associated_EditableToggleField = f;
	this.submit_command = submit_command;
	this.submit_request_object = submit_request_object;

}

new TestSubmitWYSIWYGEditCommand();

TestSubmitWYSIWYGEditCommand.prototype.execute = function() { 

	alert ( "Submit" );

}

















/**
* TextEDITButtonFactory
*
* Generate a button which will turn a Text editor on and off within the EditableToggleField 
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
**/
function TextEDITButtonFactory( f, style_set ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
}

new TextEDITButtonFactory();

TextEDITButtonFactory.prototype.build = function() { 

	var rbut = new SimpleButtonWidget( this.style_set, new SwitchToTextEditCommand( this.editable_toggle_field ) );
	
	rbut.addContentNode( textToDOM( "span", "EDIT" ) );

	return rbut;

}

/**
* SwitchToTextEditCommand
*
* The command which will build the Text editor and populate the EditableToggleField 
*
* @param f: The editable toggle field
**/
function SwitchToTextEditCommand( f ) { 
	this.associated_EditableToggleField = f;
}

new SwitchToTextEditCommand();

SwitchToTextEditCommand.prototype.execute = function () { 

	//generate the Text editor
	var tform = new HGForm();
	var tedit = new HGFormElement( 
		"text" ,
		this.associated_EditableToggleField.unrendered_content ,
		"toggle_text_editor" ,
		100 ,
		null ,
		100 ,
		null ,
		this.associated_EditableToggleField.edit_value_population_command 
	);

	tform.addHGFormElement( tedit );

	//toggle the field
	this.associated_EditableToggleField.toggleContent( tform.form );

	//set the button configuration
	this.associated_EditableToggleField.setButtonConfigurationToEdit();

	this.associated_EditableToggleField.activeEditor = tform;

}

/**
* TextCANCELButtonFactory
*
* Generate the CANCEL button
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
**/
function TextCANCELButtonFactory( f, style_set ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
}

new TextCANCELButtonFactory();

TextCANCELButtonFactory.prototype.build = function() { 

	var rbut = new SimpleButtonWidget( this.style_set, new CancelTextEditCommand( this.editable_toggle_field ) );
	
	rbut.addContentNode( textToDOM( "span", "CANCEL" ) );

	return rbut;

}

/**
* CancelTextEditCommand
*
* Remove the Text Editor from the Toggle Field and replace it with the original content
*
* @param f: The editable toggle field
**/
function CancelTextEditCommand( f ) { 
	this.associated_EditableToggleField = f;
}

new CancelTextEditCommand();

CancelTextEditCommand.prototype.execute = function () { 

	//toggle the field
	this.associated_EditableToggleField.unToggleContent();

	this.associated_EditableToggleField.setButtonConfigurationToDefault();

	this.associated_EditableToggleField.activeEditor = null;

}

/**
* TextSUBMITButtonFactory
*
* Generate the SUBMIT button
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
* @param submit_command: The command to execute upon submit request
**/
function TextSUBMITButtonFactory( f, style_set, submit_command ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
	this.submit_command = submit_command;
}

new TextSUBMITButtonFactory();

TextSUBMITButtonFactory.prototype.build = function() {

	var rbut = new SimpleButtonWidget( this.style_set, this.submit_command );
	
	rbut.addContentNode( textToDOM( "span", "SUBMIT" ) );

	return rbut;

}

/**
* SelectionEDITButtonFactory
*
* Generate a button which will turn a Text editor on and off within the EditableToggleField 
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
**/
function SelectionEDITButtonFactory( f, style_set) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
}

new SelectionEDITButtonFactory();

SelectionEDITButtonFactory.prototype.build = function() {

	var rbut = new SimpleButtonWidget( this.style_set, new SwitchToSelectionEditCommand( this.editable_toggle_field ) );
	
	rbut.addContentNode( textToDOM( "span", "EDIT" ) );

	return rbut;

}

/**
* SwitchToSelectionEditCommand
*
* The command which will build the Selection editor and populate the EditableToggleField 
*
* @param f: The editable toggle field
**/
function SwitchToSelectionEditCommand( f ) { 
	this.associated_EditableToggleField = f;
}

new SwitchToSelectionEditCommand();

SwitchToSelectionEditCommand.prototype.execute = function () { 

	//generate the Text editor
	var tform = new HGForm();
	var tedit = new HGFormElement( 
		"selection" ,
		null ,
		"toggle_selection_editor" ,
		null ,
		null ,
		null ,
		null ,
		this.associated_EditableToggleField.edit_value_population_command 
	);

	tform.addHGFormElement( tedit );

	//toggle the field
	this.associated_EditableToggleField.toggleContent( tform.form );

	//set the button configuration
	this.associated_EditableToggleField.setButtonConfigurationToEdit();

	this.associated_EditableToggleField.activeEditor = tform;

}

/**
* SelectionCANCELButtonFactory
*
* Generate the CANCEL button
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
**/
function SelectionCANCELButtonFactory( f, style_set ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
}

new SelectionCANCELButtonFactory();

SelectionCANCELButtonFactory.prototype.build = function() {

	var rbut = new SimpleButtonWidget( this.style_set, new CancelSelectionEditCommand( this.editable_toggle_field ) );
	
	rbut.addContentNode( textToDOM( "span", "CANCEL" ) );

	return rbut;

}

/**
* CancelSelectionEditCommand
*
* Remove the Text Editor from the Toggle Field and replace it with the original content
*
* @param f: The editable toggle field
**/
function CancelSelectionEditCommand( f ) { 
	this.associated_EditableToggleField = f;
}

new CancelSelectionEditCommand();

CancelSelectionEditCommand.prototype.execute = function () { 

	//toggle the field
	this.associated_EditableToggleField.unToggleContent();

	this.associated_EditableToggleField.setButtonConfigurationToDefault();

	this.associated_EditableToggleField.activeEditor = null;

}

/**
* SelectionSUBMITButtonFactory
*
* Generate the SUBMIT button
*
* @param f: The editable toggle field
* @param style_set
*          -style_set_button_over
*          -style_set_button_out
* @param submit_command: The command to execute upon submit request
**/
function SelectionSUBMITButtonFactory( f, style_set, submit_command ) { 
	this.editable_toggle_field = f;
	this.style_set = style_set;
	this.submit_command = submit_command;
}

new SelectionSUBMITButtonFactory();

SelectionSUBMITButtonFactory.prototype.build = function() { 

	var rbut = new SimpleButtonWidget( this.style_set, this.submit_command );
	
	rbut.addContentNode( textToDOM( "span", "SUBMIT" ) );

	return rbut;

}

