/*
 *
 * Copyright © 2015-2016 Antergos
 *
 * greeter.js
 *
 * This file is part of lightdm-webkit-theme-antergos
 *
 * lightdm-webkit-theme-antergos is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * lightdm-webkit-theme-antergos is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * The following additional terms are in effect as per Section 7 of this license:
 *
 * The preservation of all legal notices and author attributions in
 * the material or in the Appropriate Legal Notices displayed
 * by works containing it is required.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
String.prototype.capitalize = function() {
	return this.charAt( 0 ).toUpperCase() + this.slice( 1 );
};
var _self;
class AntergosTheme {
	constructor() {
		this.debug = this.cache_get( 'debug', 'enabled' );
		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.$msg_area = $( '#showMsg' );
		this.lang = window.navigator.language.split( '-' )[ 0 ].toLocaleLowerCase();
		this.translations = window.ant_translations;
		this.initialize();
	}
	initialize() {
		this.initialize_clock();
		this.prepare_login_panel_header();
		this.prepare_user_list();
		this.prepare_session_list();
		this.prepare_system_action_buttons();
		this.register_callbacks();
	}
	/**
	 * Add text to the debug log element (accessible from the login screen).
	 *
	 * @param {string} text - To be added to the log.
	 */
	log( text ) {
		if ( 'true' === this.debug || true ) {
			$( '#logArea' ).append( `${text}
` );
		}
	}
	/**
	 * Get a key's value from localStorage. Keys can have two or more parts.
	 * For example: "ant:user:john:session".
	 *
	 * @param {...string} key_parts - Strings that are combined to form the key.
	 */
	cache_get( ...key_parts ) {
		var key = `ant`,
			index = 0;
		for ( var part of key_parts ) {
			key += `:${part}`;
			index += 1;
		}
		return localStorage.getItem( key );
	}
	/**
	 * Set a key's value in localStorage. Keys can have two or more parts.
	 * For example: "ant:user:john:session".
	 *
	 * @param {string} value - The value to set.
	 * @param {...string} key_parts - Strings that are combined to form the key.
	 */
	cache_set( value, ...key_parts ) {
		var key = `ant`,
			index = 0;
		for ( var part of key_parts ) {
			key += `:${part}`;
			index += 1;
		}
		return localStorage.setItem( key, value );
	}
	/**
	 * Register callbacks for LightDM as well as any others that haven't been registered elsewhere.
	 */
	register_callbacks() {
		$( document ).keydown( this, this.key_press_handler);
		$('.cancel_auth').click(this, this.cancel_authentication);
		$('.submit_passwd').click(this, this.submit_password);
		window.show_prompt = this.show_prompt;
		window.show_message = this.show_message;
		window.start_authentication = this.start_authentication;
		window.cancel_authentication = this.cancel_authentication;
		window.authentication_complete = this.authentication_complete;
	}
	/**
	 * Initialize the user list.
	 */
	prepare_user_list() {
		var tux = 'img/antergos-logo-user.png',
			template;
		// Loop through the array of LightDMUser objects to create our user list.
		for ( var user of lightdm.users ) {
			var last_session = this.cache_get( 'user', user.name, 'session' ),
				image_src = user.image.length ? user.image : tux;
			if ( null === last_session ) {
				// For backwards compatibility
				last_session = localStorage.getItem( user.name );
				if ( null === last_session ) {
					// This user has never logged in before let's enable the system's default
					// session.
					last_session = lightdm.default_session;
				}
				this.cache_set( last_session, 'user', user.name, 'session' );
			}
			this.log( `Last session for ${user.name} was: ${last_session}` );
			template = `
				
					 ${user.display_name}
					
				`;
			// Register event handler here so we don't have to iterate over the users again later.
			$( template ).appendTo( this.$user_list ).click( this, this.start_authentication ).children( 'img' ).on( 'error', this.image_not_found );
		} // END for ( var 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 ( var session of lightdm.sessions ) {
			var css_class = session.name.replace( / /g, '' ),
				template;
			this.log( `Adding ${session.name} to the session list...` );
			template = `
					${user.display_name}
					
				`;
			// Register event handler here so we don't have to iterate over the users again later.
			$( template ).appendTo( this.$user_list ).click( this, this.start_authentication ).children( 'img' ).on( 'error', this.image_not_found );
		} // END for ( var 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 ( var session of lightdm.sessions ) {
			var css_class = session.name.replace( / /g, '' ),
				template;
			this.log( `Adding ${session.name} to the session list...` );
			template = `
				
					${session.name}
				`;
			$( template ).appendTo( this.$session_list ).click( this, this.session_toggle_handler );
		} // END for (var session of lightdm.sessions)
		$( '.dropdown-toggle' ).dropdown();
	}
	/**
	 * Initialize the system action buttons
	 */
	prepare_system_action_buttons() {
		var actions = {
				shutdown: "power-off",
				hibernate: "asterisk",
				suspend: "arrow-down",
				restart: "refresh"
			},
			template;
		for ( var action of Object.keys( actions ) ) {
			var cmd = `can_${action}`;
			console.log( action );
			template = `
				
					
				`;
			if ( lightdm[ cmd ] ) {
				$( template ).appendTo( $( this.$actions_container ) ).click( action, ( event ) => {
					lightdm[ event.data ]();
				} );
			}
		} // END for (var [action, icon] of actions)
		$( '[data-toggle=tooltip]' ).tooltip();
	}
	initialize_clock() {
		var saved_format = this.cache_get( 'clock', 'time_format' ),
			format = (null !== saved_format) ? saved_format : 'LT',
			detected_language = null;
		// Workaround for moment.js bug: https://github.com/moment/moment/issues/2856
		for ( var lang of window.navigator.languages ) {
			try {
				detected_language = lang.split( '-' )[ 0 ].toLowerCase();
				break;
			} catch ( err ) {
				this.log( String( err ) );
			}
		}
		if ( null === detected_language ) {
			detected_language = 'en';
		}
		moment.locale( detected_language );
		this.$clock.html( moment().format( format ) );
		setInterval( () => {
			this.$clock.html( moment().format( format ) );
		}, 60000 );
	}
	show_user_list() {
		if ( $( this.$clock_container ).hasClass( 'in' ) ) {
			$( '#trigger' ).trigger( 'click' );
			this.user_list_visible = true;
		}
		if ( $( this.$user_list ).length <= 1 ) {
			$( this.$user_list ).find( 'a' ).trigger( 'click', this );
		}
	}
	prepare_login_panel_header() {
		var greeting = null;
		if ( this.translations.hasOwnProperty( this.lang ) ) {
			greeting = this.translations[ this.lang ];
		} else {
			for ( var lang of window.navigator.languages ) {
				if ( this.translations.hasOwnProperty( lang ) ) {
					greeting = this.translations[ lang ];
					break;
				}
			}
			greeting = (null === greeting) ? 'Welcome!' : greeting;
		}
		$( '.welcome' ).text( greeting );
		$( '#hostname' ).append( lightdm.hostname );
	}
	start_authentication( event ) {
		var user_id = $( this ).attr( 'id' ),
			selector = `.${user_id}`,
			self = event.data,
			user_session = self.cache_get( 'user', user_id, 'session' );
		if ( self.auth_pending || null !== self.selected_user ) {
			lightdm.cancel_authentication();
			self.log( `Authentication cancelled for ${self.selected_user}` );
			self.selected_user = null;
		}
		self.log( `Starting authentication for ${user_id}.` );
		self.selected_user = user_id;
		// CSS hack to workaround webkit bug
		if ( $( self.$user_list ).children().length > 3 ) {
			$( self.$user_list ).css( 'column-count', 'initial' ).parent().css( 'max-width', '50%' );
		}
		$( selector ).addClass( 'hovered' ).siblings().hide();
		$( '.fa-toggle-down' ).hide();
		self.log( `Session for ${user_id} is ${user_session}` );
		$( `[data-session-id="${user_session}"]` ).parent().trigger( 'click', this );
		$( '#session-list' ).removeClass( 'hidden' ).show();
		$( '#passwordArea' ).show();
		$( '.dropdown-toggle' ).dropdown();
		self.auth_pending = true;
		lightdm.start_authentication( user_id );
	}
	cancel_authentication(event) {
		var self = event.data,
			selectors = [ '#statusArea', '#timerArea', '#passwordArea', '#session-list' ];
		for ( var selector of selectors ) {
			$( selector ).hide();
		}
		lightdm.cancel_authentication();
		self.log( 'Cancelled authentication.' );
		// CSS hack to work-around webkit bug
		if ( $( self.$user_list ).children().length > 3 ) {
			$( self.$user_list ).css( 'column-count', '2' ).parent().css( 'max-width', '85%' );
		}
		$( '.hovered' ).removeClass( 'hovered' ).siblings().show();
		$( '.fa-toggle-down' ).show();
		self.selected_user = null;
		self.auth_pending = false;
	}
	authentication_complete() {
		var selected_session = $( '.selected' ).attr( 'data-session-id' );
		_self.auth_pending = false;
		_self.cache_set( selected_session, 'user', lightdm.authentication_user, 'session' );
		$( '#timerArea' ).hide();
		if ( lightdm.is_authenticated ) {
			lightdm.login( lightdm.authentication_user, selected_session );
		} else {
			$( '#statusArea' ).show();
		}
	}
	submit_password(event) {
		lightdm.provide_secret( $( '#passwordField' ).val() );
		$( '#passwordArea' ).hide();
		$( '#timerArea' ).show();
	}
	session_toggle_handler( event ) {
		var self = event.data,
			$session = $(this).children('a'),
			session_name = $session.text(),
			session_key = $session.attr( 'data-session-id' );
		console.log($session);
		$session.parents( '.btn-group' ).find( '.selected' ).attr( 'data-session-id', session_key ).html( session_name );
	}
	key_press_handler( event ) {
		var self = event.data,
			action;
		switch ( event.which ) {
			case 13:
				action = self.auth_pending ? self.submit_password() : ! self.user_list_visible ? self.show_user_list() : 0;
				self.log( action );
				break;
			case 27:
				action = self.auth_pending ? self.cancel_authentication() : 0;
				self.log( action );
				break;
			case 32:
				action = (! self.user_list_visible && ! self.auth_pending) ? self.show_user_list() : 0;
				self.log( action );
				break;
			default:
				break;
		}
	}
	/**
	 * User image on('error') handler.
	 */
	image_not_found( source ) {
		source.onerror = "";
		source.src = 'img/antergos-logo-user.png';
		return true;
	}
	/**
	 * LightDM Callback - Show password prompt to user.
	 *
	 * @param text
	 */
	show_prompt( text ) {
		$( '#passwordField' ).val( "" );
		$( '#passwordArea' ).show();
		$( '#passwordField' ).focus();
	}
	/**
	 * LightDM Callback - Show message to user.
	 *
	 * @param msg
	 */
	show_message( msg ) {
		if ( msg.length > 0 ) {
			$( this.$msg_area ).html( msg );
			$( '#passwordArea' ).hide();
			$( this.$msg_area_container ).show();
		}
	}
}
$( window ).load( function() {
	_self = new AntergosTheme();
} );