<?php
/**
 * The icon's functionalities are located here.
 * @package Fonts for Visual Composer.
 */

if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly.
}
if ( ! class_exists( 'FontsForVC' ) ) {

	/**
	 * The class that does the functions.
	 */
	class FontsForVC {

		/**
		 * Holds all the styles which we're going to print out in the footer.
		 *
		 * @var array
		 */
		public $css = array();

		/**
		 * Holds all the font names to load in the frontend.
		 *
		 * @var array
		 */
		public $fonts = array();

		/**
		 * Holds all the Google Fonts loaded from function-google-fonts.php
		 *
		 * @var array
		 */
		public $all_fonts = array();

		/**
		 * Hook into WordPress.
		 *
		 * @return void.
		 * @since 1.0
		 */
		function __construct() {

			// Add the font parameters to shortcodes.
			add_action( 'init', array( $this, 'add_font_param' ), 999 );

			// Add the font class to the shortcode outputs.
			add_filter( 'vc_shortcodes_css_class', array( $this, 'add_font_class' ), 999, 3 );

			// Print out the font styles in the footer.
			add_action( 'wp_footer', array( $this, 'add_font_scripts' ) );

			// Add our own custom VC param for picking fonts.
			add_action( 'after_setup_theme', array( $this, 'create_font_param' ) );

			// Add the necessary admin scripts.
			add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
		}

		/**
		 * Adds the font parameter to VC elements.
		 */
		public function add_font_param() {
			if ( ! function_exists( 'vc_add_param' ) ) {
				return;
			}

			$attributes = array(
				array(
					'type' => 'fnt_picker',
					'param_name' => 'fnt_family',
					'heading' => __( 'Normal Font', GAMBIT_VC_FONTS ),
					'value' => '',
					'group' => __( 'Fonts', GAMBIT_VC_FONTS ),
				),
				array(
					'type' => 'fnt_picker',
					'param_name' => 'fnt_family_h1',
					'heading' => __( 'Heading 1 Font (H1)', GAMBIT_VC_FONTS ),
					'value' => '',
					'group' => __( 'Fonts', GAMBIT_VC_FONTS ),
				),
				array(
					'type' => 'fnt_picker',
					'param_name' => 'fnt_family_h2',
					'heading' => __( 'Heading 2 Font (H2)', GAMBIT_VC_FONTS ),
					'value' => '',
					'group' => __( 'Fonts', GAMBIT_VC_FONTS ),
				),
				array(
					'type' => 'fnt_picker',
					'param_name' => 'fnt_family_h3',
					'heading' => __( 'Heading 3 Font (H3)', GAMBIT_VC_FONTS ),
					'value' => '',
					'group' => __( 'Fonts', GAMBIT_VC_FONTS ),
				),
				array(
					'type' => 'fnt_picker',
					'param_name' => 'fnt_family_h4',
					'heading' => __( 'Heading 4 Font (H4)', GAMBIT_VC_FONTS ),
					'value' => '',
					'group' => __( 'Fonts', GAMBIT_VC_FONTS ),
				),
				array(
					'type' => 'fnt_picker',
					'param_name' => 'fnt_family_h5',
					'heading' => __( 'Heading 5 Font (H5)', GAMBIT_VC_FONTS ),
					'value' => '',
					'group' => __( 'Fonts', GAMBIT_VC_FONTS ),
				),
				array(
					'type' => 'fnt_picker',
					'param_name' => 'fnt_family_h6',
					'heading' => __( 'Heading 6 Font (H6)', GAMBIT_VC_FONTS ),
					'value' => '',
					'group' => __( 'Fonts', GAMBIT_VC_FONTS ),
				)
			);

			// These are all the shortcodes we will add the fonts to.
			vc_add_params( 'vc_row', $attributes );
			vc_add_params( 'vc_row_inner', $attributes );
			vc_add_params( 'vc_column', $attributes );
			vc_add_params( 'vc_column_text', $attributes );
		}

		/**
		 * Adds the special font class to the affected VC elements.
		 *
		 * @param string $classes The current classes of the element.
		 * @param object $sc The shortcode object.
		 * @param object $atts The attributes of the shortcode.
		 *
		 * @return string The modified classes
		 */
		public function add_font_class( $classes, $sc, $atts ) {

			// Go through the different parameters for different tags.
			$tags = array( '', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' );

			$overall_class = 'fnt';
			foreach ( $tags as $tag ) {

				$attr = 'fnt_family' . ( ! empty( $tag ) ? '_' : '' ) . $tag;

				if ( empty( $atts[ $attr ] ) ) {
					continue;
				}

				$overall_class .= '_' . strtolower( preg_replace( '/[^\w]+/', '_', $atts[ $attr ] ) ) . $tag;
			}

			if ( 'fnt' === $overall_class ) {
				return $classes;
			}

			if ( array_key_exists( $overall_class, $this->css ) ) {
				return $classes . ' ' . $overall_class . ' ';
			}

			$css = '';
			foreach ( $tags as $tag ) {

				$attr = 'fnt_family' . ( ! empty( $tag ) ? '_' : '' ) . $tag;

				if ( empty( $atts[ $attr ] ) ) {
					continue;
				}

				$font = $atts[ $attr ];

				// Generate a class name based on all the selected fonts.
				// $class = 'fnt_' . strtolower( preg_replace( '/[^\w]+/', '_', $font ) );

				// Add the font name to the list of fonts to load.
				if ( ! array_search( $font, $this->fonts ) ) {
					$this->fonts[] = $font;
				}

				// Generate the CSS that we need to implement the fonts.
				if ( ! empty( $tag ) ) {
					$tagClass = sprintf( '.%s %s, %s %s *', $overall_class, $tag, $overall_class, $tag );
				} else {
					$tagClass = sprintf( '.%s, .%s *', $overall_class, $overall_class );
				}
				$css .= $tagClass . ' { font-family: "' . $font . '";}';

			}

			$this->css[ $overall_class ] = $css;

			return $classes . ' ' . $overall_class . ' ';
		}

		/**
		 * Prints out the necessary styles & scripts to load our fonts.
		 */
		public function add_font_scripts() {
			if ( count( $this->css ) ) {

				/**
				 * Styles.
				 */

				echo '<style>';

				// While webfont isn't finished loading, hide the affected elements first.
				// This is to prevent FOUT.
				echo 'html:not(.wf-active) [class*="fnt_"] { visibility: hidden; }';

				// Print out our font styles.
				echo implode( ' ', array_values( $this->css ) );

				echo '</style>';

				/**
				 * Scripts.
				 */

				$fonts = array();
				foreach ( $this->fonts as $font ) {

					// Add subsets & variations.
					$fonts[] = $font;
				}

				// Print out the loader script.
				echo '<script>
				( function( d ) {
					WebFontConfig = {
						google: {
							families: [\'' . implode( '\', \'', $fonts ) . '\']
						}
					};

					if ( "undefined" !== typeof WebFont ) {
						WebFont.load( WebFontConfig );
					}

					var wf = d.createElement( "script" ), s = d.scripts[0];
					wf.src = "https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js?lol";
					wf.async = true;
					s.parentNode.insertBefore( wf, s );
				} )( document );
				</script>';
			}
		}

		/**
		 * Register our font parameter in VC.
		 */
		public function create_font_param() {
			if ( ! function_exists( 'vc_add_shortcode_param' ) ) {
				return;
			}

			vc_add_shortcode_param( 'fnt_picker', array( $this, 'create_font_picker_field' ), plugins_url( 'fonts-vc/js/admin.js', __FILE__ )  );
		}

		/**
		 * Enqueue all the needed scripts in the backend.
		 */
		public function admin_enqueue_scripts() {
			if ( ! function_exists( 'vc_editor_post_types' ) ) {
				return;
			}

			global $current_screen;
			if ( false !== array_search( $current_screen->post_type, vc_editor_post_types() ) ) {
				wp_enqueue_style( 'fnt_select2', plugins_url( 'fonts-vc/css/select2.min.css', __FILE__ ), array(), VERSION_GAMBIT_VC_FONTS );
				wp_enqueue_script( 'fnt_select2', plugins_url( 'fonts-vc/js/select2.js', __FILE__ ), array(), VERSION_GAMBIT_VC_FONTS );
				wp_enqueue_script( 'webfontloader', '//ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js', array(), VERSION_GAMBIT_VC_FONTS );
			}
		}


		/**
		 * Creates our own font picker parameter for VC.
		 *
		 * @since 1.0
		 *
		 * @param array $settings The settings array from existing VC fields.
		 * @param string $value As specified.
		 */
		public function create_font_picker_field( $settings, $value ) {

			if ( empty( $this->all_fonts ) ) {
				require_once( 'function-google-fonts.php' );
				$this->all_fonts = fvc_get_all_google_fonts();
			}

			$select = '<option value="" ' . selected( $value, '', false ) . '>— ' . __( 'Default theme font', GAMBIT_VC_FONTS ) . ' —</option>';
			foreach ( array_keys( $this->all_fonts ) as $font ) {
				$select .= '<option value="' . esc_attr( $font ) . '" ' . selected( $value, $font, false ) . ' style="font-family: \"' . $font . '\"">' . esc_html( $font ) . '</option>';
			}

			return '<div>'
				  . '<style>.fnt_picker_field + .select2-container { width: 100% !important; } .select2-container {
					z-index: 999999;
				} .select2-results__option {     line-height: 1em; font-size: 22px; }</style>'
				  . '<select name="' . $settings['param_name'] . '" '
				  . 'data-param-name="' . $settings['param_name'] . '" '
				  . 'data-placeholder="— ' . __( 'Default theme font', GAMBIT_VC_FONTS ) . ' —"'
				  . 'class="wpb_vc_param_value wpb-textinput '
				  . $settings['param_name'] . ' ' . $settings['type'] . '_field" '
				  . '>' . $select . '</select>'
			  .'</div>';
		}
	}

	new FontsForVC();
} // End if().
