/* class */ function FileUploadController( form, callback ) {
	this.setCompletionCallback( callback );
	this.bindForm( form );
	return;  // or browser will think the document is still open
	}
	
extend( FileUploadController.prototype, {

	_form				:	null
,	getForm				:	function( ) {
		return this._form;
		}
,	setForm				:	function( v ) {
		this._form = v;
		return this;
		}
		
,	_key				:	null
,	getKey				:	function( ) {
		return this._key;
		}
,	setKey				:	function( v ) {
		this._key = v;
		if( this.getAPCNode( ) ) {
			this.getAPCNode( ).value	= v;
			}
		return this;
		}

,	_APCNode							:	null
,	getAPCNode							:	function( ) {
		return this._APCNode;
		}
,	setAPCNode							:	function( v ) {
		this._APCNode = v;
		this._APCNode.value = this.getKey( );
		return this;
		}

,	_frame								:	null
,	getFrame							:	function( ) {
		return this._frame;
		}
,	setFrame							:	function( v ) {
		this._frame = v;
		return this;
		}

,	_litebar    						:	null
,	getLitebar							:	function( ) {
		return this._litebar;
		}
,	setLitebar							:	function( v ) {
		this._litebar = v;
		return this;
		}

,   _available                          :   true
,   isAvailable                         :   function( ) {
        return this._available;
    }
,   setAvailable                        :   function( v ) {
        this._available = v;
        return this;
    }
		
,	_completionCallback					:	null
,	getCompletionCallback				:	function( ) {
		return this._completionCallback;
		}
,	setCompletionCallback				:	function( v ) {
		this._completionCallback = v;
		return this;
		}

,	onSubmitComplete					:	function( ) {
		this.getCompletionCallback( )( );
		this.setKey( 'auto_' +  parseInt( Math.random( ) * 100000 ) );
		}

,   _frameOnloadHandler                 :   null
,   getFrameOnloadHandler               :   function( ) {
        return this._frameOnloadHandler;
        }
,   setFrameOnloadHandler               :   function( v ) {
        this._frameOnloadHandler = v;
        return this;
        }

,   bindFrameOnloadHandler              : function( ) {
        var frame   = this.getFrame( );
        
        attachHandler(
              frame
            ,'onload'
            , chainHandlers(
                  frame.onload
                , this.getFrameOnloadHandler( )
              )
            );
        }

,	bindForm			: 	function( form ) {
		this.setForm( form );
        
        // Ensure the clicked button is sent, and the form has file inputs
        var hasFiles = false;
        for( var i = 0; i < form.elements.length; i++ ) {
            element = form.elements[ i ];
            
            switch( element.type ) {
                case 'submit':
                    element.onclick = chainHandlers(
                          element.onclick
                        , function( ) {
                            // cloning and changing the type choked ie7.
                            field = document.createElement( 'input' );
                            
                            field.id = this.id;
                            field.type = 'hidden';
                            field.name = this.name;
                            field.value = this.value;
                            
                            this.parentNode.appendChild( field );
                          }
                    );
                    break;
                
                case 'file':
                    hasFiles = true;
                    break;
            }
        }
        if( !hasFiles ) {
            this.setAvailable( false );
            return;
        }
        
		var key = 'iframe_' + parseInt( Math.random( ) * 100000 );

		/**
		 *	@browser IE
		 *	Internet Explorer is an amazing piece of software; you can not 
		 *	actually set the `name' or `id' elements of an Iframe
		 *	programatically once it has been created. They'll report their new
		 *	values but the frame will not work correctly. Instead, we use
		 *	some sort of ridiculous createElement() syntax.
		 */
		var iframe;
		if( isIE( ) ) {
			iframe = document.createElement(
				'<iframe name="' + key + '" id="' + key + '">'
				);
			}
		else {
			iframe  	= document.createElement( 'iframe' );
			iframe.name = key;
			iframe.id   = key;
			}

		form.appendChild( iframe );

		this.setFrame( iframe );
		iframe.style.visibility = 'hidden';
		iframe.style.height		= '5px';
		iframe.style.width      = '5px';
		iframe.style.position	= 'absolute';
		iframe.style.left		= '-9000px';
			
		form.onsubmit = chainHandlers(
			 form.onsubmit
			,bind( this, 'submit' )
			);/**/
		
		var apc = null;

		for( var ii = 0; ii < form.elements.length; ii++ ) {
			if( form.elements[ ii ].name == 'APC_UPLOAD_PROGRESS' ) {
				apc = form.elements[ ii ];
				break;
				}
			}

		if( !apc ) {
			apc = document.createElement( 'input' );
				apc.type = 'hidden';
				apc.name = 'APC_UPLOAD_PROGRESS';
			form.insertBefore( apc, form.firstChild );
			}

		this.setAPCNode( apc );
		this.setKey( 'auto_' +  parseInt( Math.random( ) * 100000 ) );
		}
		
,	submit				:	function( ) {
        
        // Ensure the form has files to upload
        var form        = this.getForm( );
        var hasFiles    = false;
        for( var i = 0; i < form.elements.length; i++ ) {
            element = form.elements[ i ];
            if( element.type == 'file'
            &&  element.value
            ) {
                hasFiles = true;
                break;
            }
        }
        if( !hasFiles ) {
            this.setAvailable( false );
            return true;
        }
        
        this.bindFrameOnloadHandler( );
		this.getForm( ).target = this.getFrame( ).name;

		this.setLitebar( new LiteboxProgressBar( ) ).getLitebar( )
			.setUpdateURI( 
				auri( 'vault/monitor/' + encodeURI( this.getKey( ) ) + '/' )
				)
			.setCompletionCallback(
				bind( this, 'onSubmitComplete' )
				)
			.show( )
			;
        
		return true;
		}

	} );


//-( VaultLitebox )-------------------------------------------------------------

/**
 *	Create a modal dialog using an arbitrary node for content.
 *
 *	@class		VaultLitebox
 *	@extends	Litebox
 */
 
/* class */ function VaultLitebox( control ) /* extends Litebox */ {
	Litebox.apply( this, [] );

	this.setCanvas( document.createElement( 'div' ) );
	this.getCanvas( ).className = 'vaultBox';
	this.setIgnoreCanvasClick( true );
	this.show();
	
	this.setBoundControl( control );
	this.build( );
	
	this.updateCanvas( );
	this.updateCanvasPosition( );
}

extend( VaultLitebox.prototype, Litebox.prototype );
extend( VaultLitebox.prototype, {
 	constructor				: 	LiteboxImage
 	
,	_boundControl			:	null
,	getBoundControl			:	function( ) {
		return this._boundControl;
		}
,	setBoundControl			:	function( v ) {
		this._boundControl = v;
		return this;
		}

,	_proxyControl			:	null
,	getProxyControl			:	function( ) {
		return this._proxyControl;
		}
,	setProxyControl			:	function( v ) {
		this._proxyControl = v;
		return this;
		}

,	_fileUploadController	: null
,	getFileUploadController	: function( ) {
		return this._fileUploadController;
	}
,	setFileUploadController	: function( v ) {
		this._fileUploadController = v;
		return this;
	}

,	_fileUploadControl				:	null
,	getFileUploadControl				:	function( ) {
		return this._fileUploadControl;
		}
,	setFileUploadControl				:	function( v ) {
		this._fileUploadControl = v;
		return this;
		}

,	_searchInput				:	null
,	getSearchInput				:	function( ) {
		return this._searchInput;
		}
,	setSearchInput				:	function( v ) {
		this._searchInput = v;
		return this;
		}

,	_activityImage				:	null
,	getActivityImage				:	function( ) {
		return this._activityImage;
		}
,	setActivityImage				:	function( v ) {
		this._activityImage = v;
		return this;
		}

,	_buttons				: { }
,	getButtons				: function( ) {
		return this._buttons;
	}

,	setQuerying				:	function( q ) {
		if( q ) {
			this.getActivityImage( ).style.display = '';
			}
		else {
			this.getActivityImage( ).style.display = 'none';
			}
		return this;
		}

		
,	_statusMessage				:	null
,	getStatusMessage				:	function( ) {
		return this._statusMessage;
		}
,	setStatusMessage				:	function( v ) {
		this._statusMessage = v;
		setHTML(
			 this.getStatusMessageNode( )
			,v + '<br />' + this.getAdditionalMessage( )
			);
		return this;
		}
		
,	getAdditionalMessage				: 	function( ) {
		var x = this.getBoundControl( ).getImageWidth( );
		var y = this.getBoundControl( ).getImageHeight( );
		if( x || y ) {
			var msg = 'Image must be ';
			if( x && y ) {
				msg = msg + x + 'px &times; ' + y + 'px.';
				}
			else {
				if( x ) {
					msg = msg + x + 'px wide.';
					}
				else {
					msg = msg + y + 'px high.';
					}
				}
			return msg;
			}
		return '';
		}
		
,	_statusMessageNode					:	null
,	getStatusMessageNode				:	function( ) {
		return this._statusMessageNode;
		}
,	setStatusMessageNode				:	function( v ) {
		this._statusMessageNode = v;
		return this;
		}

,	build								:	function( ) {
		var canvas = this.getCanvas( );
		var form;
		
		if( !isIE6( ) ) {
			canvas.appendChild( form = this.buildFileUploadForm( ) );
			canvas.appendChild( document.createElement( 'hr' ) );
			
			this.setFileUploadController( form._controller );
		}
		
		canvas.appendChild( this.buildLiveSearchNode( ) );
		canvas.appendChild( this.buildLiveResultNode( ) );
		canvas.appendChild( this.buildDialogButtons( ) );
	}
 	
,	buildLiveSearchNode		:	function( ) {

		var node = document.createElement( 'table' );
			node.className = 'searchControls';
			var findRow = node.insertRow( 0 );
				var findLabel = findRow.insertCell( 0 );
					findLabel.className = 'label';
					setText( findLabel, 'Find:' );
				var findInput = findRow.insertCell( 1 );
					this.setSearchInput( this.buildSearchInput( ) );
					findInput.appendChild( this.getSearchInput( ) );
				var activityCell = findRow.insertCell( 2 );
					activityCell.rowSpan = 2;
					activityCell.className = 'activity';
					var activityImage = document.createElement( 'img' );
						activityImage.src = 
							auri( 'resource/uicon/status_wait_e3e3e3.gif' );
						this.setActivityImage( activityImage );
						this.setQuerying( false );
						activityCell.appendChild( activityImage );
				var selectionCell = findRow.insertCell( 3 );
					selectionCell.rowSpan = 2;
					selectionCell.className = 'currentImage';
					this.setProxyControl(
						new VaultControl(
							 selectionCell
							,document.createElement( 'input' )
							,this.getBoundControl( ).getAssetID( )
							,this.getBoundControl( ).getDescriptionMarkup( )
							,false
							)
						);
			var statusRow = node.insertRow( 1 );
				var statusLabel = statusRow.insertCell( 0 );
					statusLabel.className = 'label';
					setText( statusLabel, 'Status:' );
				var statusInput = statusRow.insertCell( 1 );
					this.setStatusMessageNode( statusInput );
					this.setStatusMessage( 'No results.' );
			
		return node;

		}
		
,	beginQuery				:	function( ) {
		this.setQuerying( true );
		this.clearSearchResults( );
		this.setStatusMessage( 'Querying...' );
		}

,	buildSearchInput		:	function( ) {
		var searchInput = document.createElement( 'input' );
			searchInput.type		= 'text';
			searchInput._q			= 0;
			searchInput.onchange	= bind( searchInput, 'query' );
			searchInput.onkeydown	= bind( searchInput, 'querySoon' );
			searchInput._box		= this;
			searchInput._oldValue	= true;
		
		searchInput.getQueryCount = function( ) {
			return this._q;
			}

		searchInput.touchQueryCount = function( ) {
			++this._q;
			return this._q;
			};

		searchInput.query = function( ) {
			if( this.value != this._oldValue ) {
				this._oldValue = this.value;
				this._box.beginQuery( );
				this.touchQueryCount( );
				
				var boundCtl = this._box.getBoundControl( );
				var p = [];
				var v = 0;
				if( v = boundCtl.getImageWidth( ) ) {
					p.push( 'x=' + encodeURI( v ) );
				}
				if( v = boundCtl.getImageHeight( ) ) {
					p.push( 'y=' + encodeURI( v ) );
				}
				if( v = boundCtl.getSavePath( ) ) {
					p.push( 'path=' + encodeURI( v ) );
				}
				
				if( p ) {
					p = '?' + p.join( '&' );
					}
				else {
					p = '';
					}
					
				LiteBridge.span(
					 auri(
					 	'vault/find/' + encodeURI( this.value ) + '/' + p
					 	)
					,bind( this._box, 'displaySearchResults' )
					);
				}
			};

		searchInput.queryNow = function( arg ) {
			if( arg == this.getQueryCount( ) ) {
				this.query( );
				}
			};

		searchInput.querySoon = function( ) {
			this._box.setStatusMessage( 'Waiting for input...' );
			var q = this.touchQueryCount( );
			var f = bind( this, 'queryNow' );
			setTimeout( bind( null, f, q ), 500 );
			};


		setTimeout( function( ) { searchInput.focus( ); }, 25 );
		
		return searchInput;
		}

,	buildLiveResultNode		:	function( ) {
		
		var t = document.createElement( 'table' );
			t.className = 'searchResults';

	
		var scr = document.createElement( 'div' );
		scr.className = 'scrollPane';
		scr.appendChild( t );
		
		this._litegrid = new LiteGrid( t, this )
			.setSupportsHover( false )
			.setSupportsSelect( false )
			;
			
		return scr;
		}
		
,	buildDialogButtons		: function( ) {
		
		var div = document.createElement( 'div' );
			div.className = 'vaultBoxButtons';
			var submit = document.createElement( 'input' );
				submit.type = 'submit';
				submit.value = 'Save';
				submit.disabled = 'disabled';
				div.appendChild( submit );
				submit.onclick = bind( this, 'save' );
				
			var cancel = document.createElement( 'input' );
				cancel.type = 'submit';
				cancel.value = 'Cancel';
				div.appendChild( cancel );
				cancel.onclick = bind( this, 'cancel' );
		
		this.getButtons( ).save = submit;
		this.getButtons( ).cancel = cancel;
		return div;
		}
		
,	buildFileUploadForm		: function( ) {
		var form = document.createElement( 'form' );
			/**
			 *	@browser ?
			 *	MSDN says `enctype', VisiBone says `encoding'. We might test
			 *	to see which ones actually work; this is pure
			 *	accuracy-by-volume.
			 */
			form.encoding = form.enctype = 'multipart/form-data';
			form.method	= 'post';
			
			var kind = this.getBoundControl( ).getAssetKind( );
			kind = kind ? kind += '/' : '';
			
			form.action = auri( 'vault/create/'+kind );
		
		var ctl = this.getBoundControl( );
		[	  [ 'vault_file_path', ctl.getSavePath( ) ]
			, [ 'vault_file_x', ctl.getImageWidth( ) ]
			, [ 'vault_file_y', ctl.getImageHeight( ) ]
		].each( function( field ) {
			var input = document.createElement( 'input' );
				input.type = 'hidden';
				input.name = field.shift( );
				input.value = field.shift( );
			form.appendChild( input );
		} );
			
		var table = document.createElement( 'table' );
			table.className = 'searchControls';
			form.appendChild( table );
			var row = table.insertRow( 0 );
				var label = row.insertCell( 0 );
					label.className = 'label';
					setHTML( label, 'Upload:' );
				var fileCell = row.insertCell( 1 );
					var file = document.createElement( 'input' );
						this.setFileUploadControl( file );
						file.type = 'file';
						file.name = 'vault_file';
						fileCell.appendChild( file );
				var buttonCell = row.insertCell( 2 );
					var btn = document.createElement( 'input' );
						btn.className = 'submit';
						btn.type 	= 'submit';
						btn.value 	= 'Upload File';
						btn._form	= form;
						buttonCell.appendChild( btn );

		form._file = file;
		form.onsubmit = chainHandlers( form.onsubmit, bind( form, function( e ){
			if( !this._file.value ) {
				alert( 'You did not select a file to upload.' );
				return abortEvent( getEvent( e ) );
			}
			return true;
		} ) );
		form._controller = new FileUploadController(
			  form
			, bind( this, 'completeUpload' )
		).setFrameOnloadHandler( bind( this, 'frameOnloadHandler' ) );
		
		return form;
	}
		
,	getRenderableFilename	: function( filename ) {
		filename = filename.replace( new RegExp( '^.*/|^.*\\\\' ), '' );
		filename = filename.replace( new RegExp( '[^a-zA-Z0-9._-]' ), '' );
		filename = filename.toLowerCase( );
		
		return filename;
	}

,	getResponse				: function( ) {
		return getIFrameXML(
			this.getFileUploadController( ).getFrame( )
		).lastChild;
	}

,	completeUpload		: function( ) { }

,	frameOnloadHandler	: function( ) {
		var rsp = this.getResponse( );
		
		var error = rsp.getElementsByTagName( 'error' );
		if( error[0] ) {
			alert( 'Error: Unable to save file.\n\n'+error[0].firstChild.nodeValue );
			return;
		}
		else {
			var warning = rsp.getElementsByTagName( 'warning' );
			if( warning[0] ) {
				alert( 'Warning: '+warning[0].firsthChild.nodeValue );
			}
		}
		
		var filename = rsp.getElementsByTagName( 'filename' )[0].firstChild.nodeValue;
		this.getFileUploadControl( ).value = null;
		
		this.getSearchInput( ).value = this.getRenderableFilename( filename );
		this.getSearchInput( ).query( );
	}
		
,	clearSearchResults		: function( ) {
		this.setResultSet( null );
		this.getResultControl( ).update( );
		this.getButtons( ).save.disabled = 'disabled';
		}
		
,	displaySearchResults	: function( results ) {
		this.setQuerying( false );
		if( results.length ) {
			this.setStatusMessage( results.length + ' results.' );
			this.setResultSet( results );
			}
		else {
			this.setStatusMessage( 'No results.' );
			this.setResultSet( null );
			}
		this.getResultControl( ).update( );
		}
		
,	setResultSet			: function( results ) {
		this._resultSet = results;

		if( this._resultSet ) {
			this.getResultControl( ).setSupportsSelect( true );
			}
		else {
			this.getResultControl( ).setSupportsSelect( false );
			}

		return this;
		}
,	getResultSet			: function( ) {
		return this._resultSet;
		}
		
,	getResultControl		: function( ) {
		return this._litegrid;
		}
	
,	getGridRows				: function( ) {
		return	this.getResultSet( )
			?	this.getResultSet( ).length
			:	1;
		}

,	getGridColumns			: function( ) {
		return	this.getResultSet( )
			?	3
			:	1;
		}

,	getGridData				: function( row, col ) {
		if( !this.getResultSet( ) ) {
			return '(No data.)';
			}
		
		row = this.getResultSet( )[ row ];
			
		switch( col ) {
			case 0:
				return '<img src="'
					+ auri( 'resource/vault/' + row[ col ] + '/thumb/64/' )
					+ '" />'
					;
		}
		
		return row[ col ];
		}
		
,	getGridClass			: function( row, col ) {
		if( !this.getResultSet( ) ) {
			return 'mu';
			}
		return [ 'thumb', 'desc', 'info nowrap' ][ col ];
		}

,	getResultTable			: function( ) {
		return this._table;
		}
		
,	didGridSelect			: function( grid, state, what, row, evt ) {
		var ctl = this.getProxyControl( );
		var set = this.getResultSet( );	
		if( set ) {
			ctl.setAssetID( set[ row ][ 0 ] );
			ctl.setDescriptionMarkup( set[ row ][ 1 ] );
			ctl.update( );
			this.getButtons( ).save.disabled = '';
		}
	}

,	cancel					: function( ) {
		this.dispose( );
		}
	
,	save					: function( ) {
		bnd = this.getBoundControl( );
		pxy = this.getProxyControl( );
		bnd.setAssetID( pxy.getAssetID( ) );
		bnd.setDescriptionMarkup( pxy.getDescriptionMarkup( ) );
		bnd.update( );
		
		this.dispose( );
		}
		
	} );



// Use this obj for public interfaces.
/* class */ function WriteOnlyVaultLitebox( control ) /* extends VaultLitebox */ {
	if( isIE6( ) ) {
		alert( 'File uploads are not supported in version 6 of Internet Explorer.' );
	}
	else {
		VaultLitebox.apply( this, [ control ] );
	}
}

extend( WriteOnlyVaultLitebox.prototype, VaultLitebox.prototype );
extend( WriteOnlyVaultLitebox.prototype, {
	
	  build: function( ) {
		var canvas = this.getCanvas( );
	  	var form;
	  	
		canvas.appendChild( form = this.buildFileUploadForm( ) );
		canvas.appendChild( document.createElement( 'hr' ) );
		canvas.appendChild( this.buildDialogButtons( ) );
		
		this.setFileUploadController( form._controller );
	  }
		
	, buildDialogButtons : function( ) {
		var div = document.createElement( 'div' );
			div.className = 'vaultBoxButtons';
			
			var cancel = document.createElement( 'input' );
				cancel.type = 'submit';
				cancel.value = 'Cancel';
				div.appendChild( cancel );
				cancel.onclick = bind( this, 'cancel' );
				
		return div;
	}

,	frameOnloadHandler	: function( ) {
		var rsp = this.getResponse( );
		
		var filename	= rsp.getElementsByTagName( 'filename' );
		var id			= rsp.getElementsByTagName( 'id' );
		var error		= rsp.getElementsByTagName( 'error' );
		
		if( error[0] ) {
			alert( 'Error: Unable to save file.\n\n'+error[0].firstChild.nodeValue );
			return;
		}
		else {
			var warning = rsp.getElementsByTagName( 'warning' );
			if( warning[0] ) {
				alert( 'Warning: '+warning[0].firstChild.nodeValue );
			}
		}
		
		if( id = parseInt( id[0].firstChild.nodeValue ) ) {
			this.getBoundControl( )
				.setAssetID( id )
				.setDescriptionMarkup( '<strong>'+this.getRenderableFilename( filename[0].firstChild.nodeValue )+'</strong>' );
			
			this.setProxyControl( this.getBoundControl( ) );
			this.save( );
			this.dispose( );
		}
		else {
			alert( 'Unable to link file ('+id+').' );
		}
	}
	
} );



/* class */ function UpdateVaultLitebox( control ) /* extends WriteOnlyVaultLitebox */ {
	WriteOnlyVaultLitebox.apply( this, [ control ] );
}

extend( UpdateVaultLitebox.prototype, WriteOnlyVaultLitebox.prototype );
extend( UpdateVaultLitebox.prototype, {
	
	buildFileUploadForm: function( ) {
		var form = WriteOnlyVaultLitebox.prototype.buildFileUploadForm.apply( this, [] );
		
		form.action = auri(
			'vault/update/'+this.getBoundControl( ).getAssetID( )+'/'
		);
		
		return form;
	}
	
} );



/*class*/ function VaultLiteGallery( liteboxID, asset ) /*extends LiteGallery*/ {
	var litebox = LiteGallery.apply( this, [ liteboxID ] );
	
	if( litebox ) {
		litebox.shouldPaint = false;
		litebox.show( );
		return;
	}
	
	this.getCanvas( ).id = 'vaultGalleryBox_'+liteboxID;
	this.getCanvas( ).className = this.getCanvas( ).className+' galleryVaultBox';
	
	this.asset = asset;
	this.setIgnoreCanvasClick( true );
	
	this.show( );
}

extend( VaultLiteGallery.prototype, LiteGallery.prototype );
extend(
	  VaultLiteGallery.prototype
	, {
		  asset: null
		, shouldPaint: true
		
		, show: function( ) {
			if( this.shouldPaintCanvas( ) ) {
			  	setHTML( this.getCanvas( ), this.paint( ) );
			  	this.didSetCanvas( );
			}
			
			bind( this, LiteGallery.prototype.show )( );
		  }
		
		, shouldPaintCanvas: function( ) {
			return this.shouldPaint;
		  }
		
		, didSetCanvas: function( ) { }
		
		, paint: function( canvas ) {
			var ext = ( isIE6( ) ) ? 'gif' : 'png';
			return '<div class="close"><a href="#" onclick="LiteboxController.getFrontLitebox( ).dispose( ); new Event( event ).stop( );" onkeypress="fireClickOnEnterKeyPress( event, this );"><img src="'+auri( 'resource/image/litebox/close.'+ext )+'" alt="Close" /></a></div>'+canvas;
		  }
	  }
);



var onYouTubePlayerReady;

/*class*/ function FlashVaultLiteGallery( asset ) /*extends VaultLiteGallery*/ {
	this.hardpoint = this.hardpoint+'_'+asset.filename;
	
	VaultLiteGallery.apply( this, [ this.hardpoint, asset  ] );
}

extend( FlashVaultLiteGallery.prototype, VaultLiteGallery.prototype );
extend(
	  FlashVaultLiteGallery.prototype
	, {
		  hardpoint: 'uvFlashVaultGalleryHardpoint'
		, swiff: null
		, status: null
		  
		, paint: function( ) {
			return bind( this, VaultLiteGallery.prototype.paint )( '<div id="'+this.hardpoint+'"><p class="alert">This content requires the <a href="http://get.adobe.com/flashplayer/">Adobe Flash Player</a>.</p></div>' );
		  }
		
		, didSetCanvas: function( ) {
			var a = this.asset;
			
			if( getFlashVersion( ) >= a.player_version ) {
				onYouTubePlayerReady = function( ) {
					$( this.getCanvas( ) )
						.getElement( 'div.close' )
						.setStyle( 'display', 'block' );
					$( this.swiff ).playVideo( );
					this.status = 'playing';
				}.bind( this );
				
				this.swiff = new Swiff(
					  a.uri+a.filename+'?enablejsapi=1&rel=0&fs=1&showinfo=0'
					, { width: a.dim_x, height: a.dim_y, container: $( this.hardpoint ), params: { allowFullScreen: 'true' } }
				);
			}
			else {
				$( this.getCanvas( ) ).addClass( 'alert' );
			}
			
			this.getCanvas( ).style.width = a.dim_x+'px';
			this.getCanvas( ).style.height = a.dim_y+'px';
		  }
		
		, hideCanvas			: function( ) {
			this.getCanvas( ).style.visibility = 'hidden';
			if( this.swiff && this.status == 'playing' ) {
				$( this.swiff ).pauseVideo( );
				this.status = 'paused';
			}
		  }
				
		, showCanvas			: function( ) {
			this.getCanvas( ).style.visibility = 'visible';
			if( this.swiff && this.status == 'paused' ) {
				$( this.swiff ).playVideo( );
				this.status = 'playing';
			}
		  }
		
		, hideFrame			: function( ) {
			this.getFrame( ).style.visibility	= 'hidden';
		  }
			
		, showFrame			: function( ) {
			this.getFrame( ).style.visibility = 'visible';
		  }
		
		, dispose:	function( ) {
			bind( this, Litebox.prototype.dispose )( );
		}
	  }
);
