' ),
					$img_el = $link.children( 'div' ),
					img_url = `url(file://${image_file})`;
				if ( image_file === this.current_background || img_url === current_bg_url ) {
					$link.addClass( 'active' );
				}
				$img_el.css( 'background-image', img_url );
				$link.addClass( 'bg clearfix' ).attr( 'data-img', img_url );
				$link.appendTo( $thumbs_container ).on( 'click', event => this.background_selected_handler(event) );
			}
			if ( ! $( '.bg.active' ).length ) {
				$random_thumbnail.addClass( 'active' );
			}
		}
	}
	/**
	 * Handle background image selected event.
	 *
	 * @param {Object} event jQuery event object.
	 */
	background_selected_handler( event ) {
		let $target = $( event.target ),
			image = $target.attr( 'data-img' );
		$( '.bg.active' ).removeClass( 'active' );
		$target.addClass( 'active' );
		if ( 'random' === image ) {
			_bg_self.random_background = _config._set( 'true', 'background_manager', 'random_background' );
			_bg_self.current_background = _bg_self.get_random_image();
		} else {
			_bg_self.random_background = _config._set( 'false', 'background_manager', 'random_background' );
			_bg_self.current_background = image;
		}
		_config._set( image, 'background_manager', 'current_background' );
		this.do_background();
	}
}
/**
 * This is the theme's main class object. It contains most of the theme's logic.
 */
class Theme {
	constructor() {
		if ( null !== _self ) {
			return _self;
		}
		_self = theme_utils.bind_this( this );
		this.tux                 = 'img/antergos-logo-user.png';
		this.user_list_visible   = false;
		this.auth_pending        = false;
		this.selected_user       = null;
		this.$user_list          = $( '#user-list2' );
		this.$session_list       = $( '#sessions' );
		this.$clock_container    = $( '#collapseOne' );
		this.$clock              = $( '#current_time' );
		this.$actions_container  = $( '#actionsArea' );
		this.$msg_area_container = $( '#statusArea' );
		this.$alert_msg_tpl      = this.$msg_area_container.children( '.alert-dismissible' ).clone();
		this.background_manager = new BackgroundManager();
		this.background_manager.initialize().then( () => this.initialize() );
		return _self;
	}
	/**
	 * Initialize the theme.
	 */
	initialize() {
		this.prepare_translations();
		this.do_static_translations();
		this.initialize_clock();
		this.prepare_login_panel_header();
		this.prepare_system_action_buttons();
		$( '#login' ).css( 'opacity', '1' );
		this.prepare_user_list();
		this.prepare_session_list();
		this.register_callbacks();
		this.background_manager.setup_background_thumbnails();
	}
	/**
	 * Register callbacks for the LDM Greeter as well as any others that haven't
	 * been registered elsewhere.
	 */
	register_callbacks() {
		this.$user_list
			.parents( '.collapse' )
			.on( 'shown.bs.collapse hidden.bs.collapse', event => this.user_list_collapse_handler(event) );
		$( document ).on( 'keydown', event => this.key_press_handler(event) );
		$( '.cancel_auth:not(.alert .cancel_auth)' ).on( 'click', event => this.cancel_authentication(event) );
		$( '.submit_passwd' ).on( 'click', event => this.submit_password(event) );
		$( '[data-i18n="debug_log"]' ).on( 'click', event => this.show_log_handler(event) );
		lightdm.show_prompt.connect( (prompt, type) => this.show_prompt(prompt, type) );
		lightdm.show_message.connect( (msg, type) => this.show_message(msg, type) );
		window.start_authentication    = event => this.start_authentication(event);
		window.cancel_authentication   = event => this.cancel_authentication(event);
		lightdm.authentication_complete.connect( () => this.authentication_complete() );
		lightdm.autologin_timer_expired.connect( event => this.cancel_authentication(event) );
	}
	/**
	 * Initialize the user list.
	 */
	prepare_user_list() {
		let template;
		// Loop through the array of LightDMUser objects to create our user list.
		for ( let user of lightdm.users ) {
			let last_session = _config._get( 'user', user.username, 'session' ),
				image_src = ( user.image && user.image.length ) ? user.image : _config.user_image;
			if ( null === last_session ) {
				// This user has never logged in before let's enable the system's default session.
				last_session = _config._set( lightdm.default_session, 'user', user.name, 'session' );
			}
			log( `Last session for ${user.name} was: ${last_session}` );
			template = `
				
					 ${user.display_name}
					${user.display_name}
					
				`;
			// Insert the template into the DOM and then register event handlers so we don't
			// have to iterate over the users again later.
			$( template )
				.appendTo( this.$user_list )
				.on( 'click', event => this.start_authentication(event) )
				.on( 'error.antergos', err => this.user_image_error_handler(err) );
		} // END for ( let user of lightdm.users )
		if ( this.$user_list.children().length > 3 ) {
			// Make the user list two columns instead of one.
			this.$user_list.css( 'column-count', '2' ).parent().css( 'max-width', '85%' );
		}
	}
	/**
	 * Initialize the session selection dropdown.
	 */
	prepare_session_list() {
		// Loop through the array of LightDMSession objects to create our session list.
		for ( let session of lightdm.sessions ) {
			let css_class = session.name.replace( / /g, '' ),
				template;
			log( `Adding ${session.name} to the session list...` );
			template = `
				
					${session.name}
				`;
			$( template )
				.appendTo( this.$session_list )
				.on( 'click', event => this.session_toggle_handler(event) );
		} // END for (var session of lightdm.sessions)
		$( '.dropdown-toggle' ).dropdown();
	}
	/**
	 * Initialize the system action buttons
	 */
	prepare_system_action_buttons() {
		let template,
			actions = {
			shutdown: 'power-off',
			hibernate: 'asterisk',
			suspend: 'arrow-down',
			restart: 'refresh'
		};
		for ( let action of Object.keys( actions ) ) {
			let cmd = `can_${action}`;
			template = `
				
					
				`;
			if ( ! lightdm[cmd] ) {
				// This action is either not available on this system or we don't have permission to use it.
				continue;
			}
			$( template )
				.appendTo( this.$actions_container )
				.on( 'click', event => this.system_action_handler(event) );
		} // END for (let [action, icon] of actions)
		$( '[data-toggle=tooltip]' ).tooltip();
		$( '.modal' ).modal( { show: false } );
	}
	/**
	 * Setup the clock widget.
	 */
	initialize_clock() {
		this.$clock.html( theme_utils.get_current_localized_time() );
		setInterval( () => _self.$clock.html( theme_utils.get_current_localized_time() ), 60000 );
	}
	/**
	 * Show the user list if its not already shown. This is used to allow the user to
	 * display the user list by pressing Enter or Spacebar.
	 */
	show_user_list( show = true ) {
		let delay = 0;
		if ( false === show ) {
			return;
		}
		if ( this.$clock_container.hasClass( 'in' ) ) {
			delay = 500;
			$( '#trigger' ).trigger( 'click' );
		}
		if ( this.$user_list.children().length <= 1 ) {
			setTimeout( () => this.$user_list.find( 'a' ).trigger( 'click', this ), delay );
		}
	}
	prepare_login_panel_header() {
		let greeting = _config.translations.greeting ? _config.translations.greeting : 'Welcome!',
			logo = is_empty( _config.logo ) ? 'img/antergos.png' : _config.logo;
		$( '.welcome' ).text( greeting );
		$( '#hostname' ).append( lightdm.hostname );
		$( '[data-greeter-config="logo"]' ).attr( 'src', logo );
	}
	prepare_translations() {
		if ( ! _config.translations.hasOwnProperty( this.lang ) ) {
			this.lang = 'en';
			for ( let lang of window.navigator.languages ) {
				if ( _config.translations.hasOwnProperty( lang ) ) {
					this.lang = lang;
					break;
				}
			}
		}
		_config.translations = _config.translations[ this.lang ];
	}
	/**
	 * Replace '${i18n}' with translated string for all elements that
	 * have the data-i18n attribute. This is for elements that are not generated
	 * dynamically (they can be found in index.html).
	 */
	do_static_translations() {
		$( '[data-i18n]' ).each( function () {
			let key = $( this ).attr( 'data-i18n' ),
				html = $( this ).html(),
				translated = _config.translations[ key ],
				new_html = html.replace( '${i18n}', translated );
			$( this ).html( new_html );
		} );
	}
	/**
	 * Start the authentication process for the selected user.
	 *
	 * @param {object} event - jQuery.Event object from 'click' event.
	 */
	start_authentication( event ) {
		let user_id = $( event.target ).attr( 'id' ),
			selector = `.${user_id}`,
			user_session_cached = _config._get( 'user', user_id, 'session' ),
			user_session = is_empty( user_session_cached ) ? lightdm.default_session : user_session_cached;
		if ( this.auth_pending || null !== this.selected_user ) {
			lightdm.cancel_authentication();
			log( `Authentication cancelled for ${this.selected_user}` );
			this.selected_user = null;
			this.auth_pending = false;
		}
		log( `Starting authentication for ${user_id}.` );
		this.selected_user = user_id;
		if ( this.$user_list.children().length > 3 ) {
			// Reset columns since only the selected user is visible right now.
			this.$user_list.css( 'column-count', 'initial' ).parent().css( 'max-width', '50%' );
		}
		$( selector ).addClass( 'hovered' ).siblings().hide();
		$( '.fa-toggle-down' ).hide();
		log( `Session for ${user_id} is ${user_session}` );
		$( `[data-session-id="${user_session}"]` ).parent().trigger( 'click', this );
		$( '#session-list' ).removeClass( 'hidden' ).show();
		$( '#passwordArea' ).show();
		$('#passwordField').focus();
		$( '.dropdown-toggle' ).dropdown();
		this.auth_pending = true;
		lightdm.authenticate( user_id );
	}
	/**
	 * Cancel the pending authentication.
	 *
	 * @param {object} event - jQuery.Event object from 'click' event.
	 */
	cancel_authentication( event ) {
		let selectors = ['#statusArea', '#timerArea', '#passwordArea', '#session-list'];
		selectors.forEach( selector => $( selector ).hide() );
		lightdm.cancel_authentication();
		log( 'Cancelled authentication.' );
		this.selected_user = null;
		this.auth_pending  = false;
		if ( $( event.target ).hasClass( 'alert' ) ) {
			/* We were triggered by the authentication failed message being dismissed.
			 * Keep the same account selected so user can retry without re-selecting an account.
			 */
			$( '#collapseTwo .user-wrap2' ).show( () => {
				$( '.list-group-item.hovered' ).trigger( 'click' );
			} );
		} else {
			if ( this.$user_list.children().length > 3 ) {
				// Make the user list two columns instead of one.
				this.$user_list.css( 'column-count', '2' ).parent().css( 'max-width', '85%' );
			}
			$( '.hovered' ).removeClass( 'hovered' ).siblings().show();
			$( '.fa-toggle-down' ).show();
		}
	}
	/**
	 * Called when the user attempts to authenticate (submits password).
	 * We check to see if the user successfully authenticated and if so tell the LDM
	 * Greeter to log them in with the session they selected.
	 */
	authentication_complete() {
		let selected_session = $( '.selected' ).attr( 'data-session-id' ),
			err_msg = _config.translations.auth_failed;
		this.auth_pending = false;
		_config._set( selected_session, 'user', lightdm.authentication_user, 'session' );
		$( '#timerArea' ).hide();
		if ( lightdm.is_authenticated ) {
			// The user entered the correct password. Let's start the session.
			$( 'body' ).fadeOut( 1000, () => lightdm.start_session( selected_session ) );
		} else {
			// The user did not enter the correct password. Show error message.
			this.show_message( err_msg, 'error' );
		}
	}
	submit_password( event ) {
		let passwd = $( '#passwordField' ).val();
		console.log(lightdm.authentication_user);
		$( '#passwordArea' ).hide();
		$( '#timerArea' ).show();
		lightdm.respond( passwd );
	}
	session_toggle_handler( event ) {
		let $session = $( event.target ).children( 'a' ),
			session_name = $session.text(),
			session_key = $session.attr( 'data-session-id' );
		$session
			.parents( '.btn-group' )
			.find( '.selected' )
			.attr( 'data-session-id', session_key )
			.html( session_name );
	}
	key_press_handler( event ) {
		let action;
		switch ( event.which ) {
			case 13:
				action = this.auth_pending ? this.submit_password : ! this.user_list_visible ? this.show_user_list : null;
				break;
			case 27:
				action = this.auth_pending ? this.cancel_authentication : null;
				break;
			case 32:
				action = ( ! this.user_list_visible && ! this.auth_pending ) ? this.show_user_list : null;
				break;
			default:
				action = null;
				break;
		}
		if ( null !== action ) {
			action();
		}
	}
	system_action_handler() {
		let action = $( this ).attr( 'id' ),
			$modal = $( '.modal' );
		$modal
			.find( '.btn-primary' )
			.text( _config.translations[ action ] )
			.on( 'click', action, function( event ) {
				$( this ).off( 'click' );
				$( 'body' ).fadeOut( 1000, () => lightdm[ event.data ]() );
			} );
		$modal
			.find( '.btn-default' )
			.on( 'click', function( event ) {
				$( this ).next().off( 'click' );
			} );
		$modal.modal( 'toggle' );
	}
	user_list_collapse_handler( event ) {
		this.user_list_visible = $( event.target ).hasClass( 'in' );
		this.show_user_list( this.user_list_visible );
	}
	user_image_error_handler( event ) {
		$( event.target ).off( 'error.antergos' );
		$( event.target ).attr( 'src', this.tux );
	}
	show_log_handler( event ) {
		if ( _config.$log_container.is( ':visible' ) ) {
			_config.$log_container.hide();
		} else {
			_config.$log_container.show();
		}
	}
	/**
	 * LightDM Callback - Show prompt to user.
	 *
	 * @param text
	 * @param type
	 */
	show_prompt( text, type ) {
		if ( 'password' === type ) {
			$( '#passwordField' ).val( '' );
			$( '#passwordArea' ).show();
			$( '#passwordField' ).focus();
		}
	}
	/**
	 * LightDM Callback - Show message to user.
	 *
	 * @param text
	 * @param type
	 */
	show_message( text, type ) {
		if ( ! text.length ) {
			log( 'show_message() called without a message to show!' );
			return;
		}
		let $msg_container = this.$msg_area_container.children( '.alert-dismissible' );
		if ( ! $msg_container.length ) {
			$msg_container = this.$alert_msg_tpl.clone();
			$msg_container.appendTo( this.$msg_area_container );
		}
		$msg_container.on( 'closed.bs.alert', event => this.cancel_authentication( event ) );
		$msg_container.html( $msg_container.html() + text );
		$( '#collapseTwo .user-wrap2' ).hide();
		this.$msg_area_container.show();
	}
}
/**
 * Initialize the theme once the window has loaded.
 */
$( window ).on( 'GreeterReady', () => {
	new ThemeConfig();
	new Theme();
} );