ShortcodesUltimateMakerEditor.Icon = ( function( $ ) {

	/**
	 * Define main object.
	 */
	var self = {};

	/**
	 * Define component elements.
	 */
	self.el = {
		body: $( 'body' ),
		field: $( '#sum-icon' ),
		value: $( '#sum-icon-value' ),
		picker: null,
		dropdown: null,
		mediaLink: null,
		mediaFrame: null
	};

	/**
	 * Define component templates.
	 */
	self.tpl = {
		general: $( '#sum-icon-tpl' ).html(),
		fa: $( '#sum-icon-fa-tpl' ).html(),
		img: $( '#sum-icon-img-tpl' ).html()
	};

	/**
	 * Retrieve l10n strings.
	 */
	self.l10n = ShortcodesUltimateMakerEditorData.l10n.Icon;

	/**
	 * Retrieve icon list.
	 */
	self.icons = ShortcodesUltimateMakerEditorData.icons;

	/**
	 * Initialize the component.
	 */
	self.init = function() {

		/**
		 * Append general template to the icon field.
		 */
		$( self.tpl.general ).appendTo( self.el.field );

		/**
		 * Define icon picker element (a.button).
		 */
		self.el.picker = self.el.field
			.children( '.sum-icon-picker' )
			.attr( 'data-label-closed', self.l10n.selectIcon )
			.attr( 'data-label-open', self.l10n.close );

		/**
		 * Define dropdown element (div with mediaLink and FontAwesome icons).
		 */
		self.el.dropdown = self.el.field
			.children( '.sum-icon-dropdown' )
			.append( self.getDropdownContent() );

		/**
		 * Define media library link element (div with nested a tag).
		 */
		self.el.mediaLink = self.el.field
			.find( '.sum-icon-media-link a' )
			.html( self.l10n.useCustomImage + '&hellip;' );

		/**
		 * Create media library frame.
		 */
		self.el.mediaFrame = wp.media( {
			library: {
				type: 'image'
			},
			title: self.l10n.selectCustomImage,
			button: {
				text: self.l10n.useSelectedImage
			},
			multiple: false
		} );

		/**
		 * Update icon picker preview.
		 */
		self.updatePreview();

		/**
		 * Setup event listeners.
		 */
		self.bindEvents();

	};

	/**
	 * Setup event listeners.
	 */
	self.bindEvents = function() {

		self.el.picker.on( 'click', self.toggleDropdown );
		self.el.dropdown.on( 'click', 'i', self.setFAIcon );
		self.el.mediaLink.on( 'click', self.openMediaLibrary );
		self.el.mediaFrame.on( 'select', self.setImgIcon );
		self.el.body.on( 'click', self.clickOutsideDropdown );

	};

	/**
	 * Update icon preview.
	 *
	 * New value will be generated depending on hidden input value.
	 */
	self.updatePreview = function() {

		var value = self.el.value.val(),
			preview = '';

		/**
		 * An <img> icon.
		 */
		if ( value.indexOf( '/' ) > -1 ) {
			preview = self.tpl.img.replace( '%ICON%', value );
		}

		/**
		 * A FontAwesome icon.
		 */
		else {
			preview = self.tpl.fa.replace( /%ICON%/g, value );
		}

		self.el.picker.html( preview );

	};

	/**
	 * Set FontAwesome icon.
	 */
	self.setFAIcon = function() {

		self.el.value.val( $( this ).attr( 'title' ) );

		self.toggleDropdown();

		self.updatePreview();

	};

	/**
	 * Set <img> icon.
	 */
	self.setImgIcon = function() {

		var attachment = self.el.mediaFrame
			.state().get( 'selection' ).first()
			.toJSON();

		self.el.value.val( attachment.url );

		self.updatePreview();

	};

	/**
	 * Open media library frame to select an image.
	 */
	self.openMediaLibrary = function( event ) {

		event.preventDefault();

		self.toggleDropdown();

		self.el.mediaFrame.open();

	};

	/**
	 * Retrieve FontAwesome icons as HTML tags.
	 */
	self.getDropdownContent = function() {

		var dropdownContent = '';

		for ( var i = self.icons.length - 1; i >= 0; i-- ) {
			dropdownContent += self.tpl.fa.replace( /%ICON%/g, self.icons[ i ] );
		}

		return dropdownContent;

	};

	/**
	 * Toggle the dropdown.
	 */
	self.toggleDropdown = function() {
		self.el.field.toggleClass( 'open' );
	};

	/**
	 * Hide dropdown on body click.
	 */
	self.clickOutsideDropdown = function( event ) {

		if ( !self.el.field.is( event.target ) &&
			self.el.field.hasClass( 'open' ) &&
			self.el.field.has( event.target ).length === 0
		) {
			self.el.field.removeClass( 'open' );
		}

	};

	/**
	 * Provide public API.
	 */
	return {
		init: self.init
	};

} )( jQuery );