<?php
namespace PowerpackElements;

use Elementor\Utils;
use PowerpackElements\Classes\PP_Helper;
use PowerpackElements\Classes\PP_Config;

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

/**
 * Main class plugin
 */
class Powerpackplugin {

	/**
	 * @var Plugin
	 */
	public static $instance = null;

	/**
	 * @var Manager
	 */
	private $_extensions_manager;

	/**
	 * @var Manager
	 */
	public $modules_manager;

	/**
	 * @var array
	 */
	private $_localize_settings = [];

	private $_settings = [];

	/**
	 * @return string
	 */
	public function get_version() {
		return POWERPACK_ELEMENTS_VER;
	}

	/**
	 * Throw error on object clone
	 *
	 * The whole idea of the singleton design pattern is that there is a single
	 * object therefore, we don't want the object to be cloned.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function __clone() {
		// Cloning instances of the class is forbidden
		_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'powerpack' ), '1.0.0' );
	}

	/**
	 * Disable unserializing of the class
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function __wakeup() {
		// Unserializing instances of the class is forbidden
		_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'powerpack' ), '1.0.0' );
	}

	/**
	 * @return Plugin
	 */
	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Include components
	 *
	 * @since 2.0.3
	 *
	 * @access private
	 */
	private function includes() {

		// Posts Helper Functions
		pp_plugin_include( 'classes/class-pp-posts-helper.php' );
		pp_plugin_include( 'classes/class-pp-posts-query-builder.php' );
		pp_plugin_include( 'modules/posts/traits/trait-posts-query-controls.php' );

		// WooCommerce Helper Functions
		if ( is_pp_woocommerce() ) {
			pp_plugin_include( 'classes/class-pp-woo-helper.php' );
		}

		// WPML Compatibility
		pp_plugin_include( 'classes/class-pp-wpml.php' );

		// Managers
		pp_plugin_include( 'includes/extensions-manager.php' );
		pp_plugin_include( 'includes/modules-manager.php' );

		// Magic Wand Functinoality
		pp_plugin_include( 'classes/class-pp-magic-wand.php' );
	}

	public function autoload( $class ) {
		if ( 0 !== strpos( $class, __NAMESPACE__ ) ) {
			return;
		}

		$filename = strtolower(
			preg_replace(
				[ '/^' . __NAMESPACE__ . '\\\/', '/([a-z])([A-Z])/', '/_/', '/\\\/' ],
				[ '', '$1-$2', '-', DIRECTORY_SEPARATOR ],
				$class
			)
		);
		$filename = POWERPACK_ELEMENTS_PATH . $filename . '.php';

		if ( is_readable( $filename ) ) {
			include $filename;
		}
	}

	public function get_localize_settings() {
		return $this->_localize_settings;
	}

	public function add_localize_settings( $setting_key, $setting_value = null ) {
		if ( is_array( $setting_key ) ) {
			$this->_localize_settings = array_replace_recursive( $this->_localize_settings, $setting_key );

			return;
		}

		if ( ! is_array( $setting_value ) || ! isset( $this->_localize_settings[ $setting_key ] ) || ! is_array( $this->_localize_settings[ $setting_key ] ) ) {
			$this->_localize_settings[ $setting_key ] = $setting_value;

			return;
		}

		$this->_localize_settings[ $setting_key ] = array_replace_recursive( $this->_localize_settings[ $setting_key ], $setting_value );
	}

	public function register_styles() {
		$settings         = \PowerpackElements\Classes\PP_Admin_Settings::get_settings();
		$debug_suffix     = ( PP_Helper::is_script_debug() ) ? '' : '.min';
		$direction_suffix = is_rtl() ? '-rtl' : '';
		$suffix           = $direction_suffix . $debug_suffix;
		$path             = ( PP_Helper::is_script_debug() ) ? 'assets/css/' : 'assets/css/min/';

		/* $widgets_with_styles = PP_Config::widgets_with_styles();
		foreach ( $widgets_with_styles as $widget_name ) {
			wp_register_style(
				"widget-pp-{$widget_name}",
				POWERPACK_ELEMENTS_URL . 'assets/css/widget-' . $widget_name . $debug_suffix . '.css',
				[],
				POWERPACK_ELEMENTS_VER
			);
		} */

		wp_register_style(
			'pp-extensions',
			POWERPACK_ELEMENTS_URL . $path . 'extensions' . $suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_register_style(
			'pp-tooltip',
			POWERPACK_ELEMENTS_URL . $path . 'tooltip' . $suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_register_style(
			'pp-filter-animations',
			POWERPACK_ELEMENTS_URL . $path . 'filter-animations' . $suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_register_style(
			'pp-image-filters',
			POWERPACK_ELEMENTS_URL . $path . 'image-filters' . $suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_register_style(
			'pp-interactive-circle-animations',
			POWERPACK_ELEMENTS_URL . $path . 'widget-interactive-circle-animations' . $suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_register_style(
			'pp-swiper',
			POWERPACK_ELEMENTS_URL . $path . 'pp-swiper' . $suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_register_style(
			'tablesaw',
			POWERPACK_ELEMENTS_URL . 'assets/lib/tablesaw/tablesaw.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_register_style(
			'fancybox',
			POWERPACK_ELEMENTS_URL . 'assets/lib/fancybox/jquery.fancybox' . $debug_suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_register_style(
			'pp-hamburgers',
			POWERPACK_ELEMENTS_URL . 'assets/lib/hamburgers/hamburgers' . $debug_suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		if ( is_pp_woocommerce() ) {
			wp_register_style(
				'pp-woocommerce',
				POWERPACK_ELEMENTS_URL . $path . 'pp-woocommerce' . $suffix . '.css',
				[],
				POWERPACK_ELEMENTS_VER
			);
		}
	}

	public function register_style_scripts() {
		$settings = \PowerpackElements\Classes\PP_Admin_Settings::get_settings();
		$suffix   = ( PP_Helper::is_script_debug() ) ? '' : '.min';
		$path     = ( PP_Helper::is_script_debug() ) ? 'assets/js/' : 'assets/js/min/';

		$this->register_styles();

		wp_register_script(
			'pp-counter',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-counter' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-login-form',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-login-form' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-progress-bar',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-progress-bar' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_localize_script(
			'pp-login-form',
			'ppLogin',
			[
				'empty_username'   => __( 'Enter a username or email address', 'powerpack' ),
				'empty_password'   => __( 'Enter password', 'powerpack' ),
				'empty_password_1' => __( 'Enter a password', 'powerpack' ),
				'empty_password_2' => __( 'Re-enter password', 'powerpack' ),
				'empty_recaptcha'  => __( 'Please check the captcha to verify you are not a robot', 'powerpack' ),
				'email_sent'       => apply_filters( 'pp_login_email_sent_message', __( 'A password reset email has been sent to the email address for your account, but may take several minutes to show up in your inbox. Please wait at least 10 minutes before attempting another reset.', 'powerpack' ) ),
				'reset_success'    => apply_filters( 'pp_login_reset_success_message', __( 'Your password has been reset successfully', 'powerpack' ) ),
				'ajax_url'         => admin_url( 'admin-ajax.php' ),
				'show_password'    => __( 'Show password', 'powerpack' ),
				'hide_password'    => __( 'Hide password', 'powerpack' ),
			]
		);

		// wp_register_script( 'pp-google-login', 'https://accounts.google.com/gsi/client', [ 'jquery', 'pp-login-form' ], POWERPACK_ELEMENTS_VER, true );

		wp_register_script( 'pp-google-recaptcha', 'https://www.google.com/recaptcha/api.js?onload=onLoadPPReCaptcha&render=explicit', [ 'jquery', 'pp-login-form' ], POWERPACK_ELEMENTS_VER, true );

		wp_register_script(
			'pp-registration-form',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-registration-form' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_localize_script(
			'pp-registration-form',
			'ppRegistration',
			[
				'invalid_username'      => __( 'This username is invalid because it uses illegal characters. Please enter a valid username.', 'powerpack' ),
				'username_exists'       => __( 'This username is already registered. Please choose another one.', 'powerpack' ),
				'empty_email'           => __( 'Please type your email address.', 'powerpack' ),
				'invalid_email'         => __( 'The email address isn&#8217;t correct!', 'powerpack' ),
				'email_exists'          => __( 'The email is already registered, please choose another one.', 'powerpack' ),
				// translators: %s denotes forward slash character.
				'password'              => sprintf( __( 'Password must not contain the character %s', 'powerpack' ), json_encode( '\\' ) ),
				// translators: %d denotes password length.
				'password_length'       => sprintf( __( 'Your password should be at least %d characters long.', 'powerpack' ), 8 ),
				'password_mismatch'     => __( 'Password does not match.', 'powerpack' ),
				'invalid_url'           => __( 'URL seems to be invalid.', 'powerpack' ),
				'recaptcha_php_ver'     => __( 'reCAPTCHA API requires PHP version 5.3 or above.', 'powerpack' ),
				'recaptcha_missing_key' => __( 'Your reCAPTCHA Site or Secret Key is missing!', 'powerpack' ),
				'show_password'         => __( 'Show password', 'powerpack' ),
				'hide_password'         => __( 'Hide password', 'powerpack' ),
				'ajax_url'              => admin_url( 'admin-ajax.php' ),
			]
		);

		wp_register_script(
			'pp-js-cookie',
			POWERPACK_ELEMENTS_URL . 'assets/lib/js-cookie/js.cookie' . $suffix . '.js',
			[],
			'3.0.5',
			true
		);

		wp_register_script(
			'jquery-event-move',
			POWERPACK_ELEMENTS_URL . 'assets/lib/jquery-event-move/jquery.event.move' . $suffix . '.js',
			[
				'jquery',
			],
			'2.0.0',
			true
		);

		wp_register_script(
			'pp-one-page-nav',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-one-page-nav' . $suffix . '.js',
			[
				'jquery',
			],
			'1.0.0',
			true
		);

		$language = '';
		$api_url  = 'https://maps.googleapis.com';

		if ( isset( $settings['google_map_lang'] ) && '' !== $settings['google_map_lang'] ) {
			$language = $settings['google_map_lang'];

			// This checks for Chinese language.
			// The Maps JavaScript API is served within China from http://maps.google.cn.
			if (
				'zh' === $settings['google_map_lang'] ||
				'zh-CN' === $settings['google_map_lang'] ||
				'zh-HK' === $settings['google_map_lang'] ||
				'zh-TW' === $settings['google_map_lang']
			) {
				$api_url = 'http://maps.googleapis.cn';
			}
		}

		$maps_params = [];
		$maps_url    = $api_url . '/maps/api/js';

		if ( isset( $settings['google_map_api'] ) && '' !== $settings['google_map_api'] ) {
			$maps_params['key'] = $settings['google_map_api'];
		}

		if ( $language ) {
			$maps_params['language']  = $language;
		}

		$maps_params['libraries'] = 'marker';

		$google_maps_url = add_query_arg(
			$maps_params,
			$maps_url
		);

		wp_register_script( 'pp-google-maps-lib', $google_maps_url, [], wp_rand(), true );

		wp_register_script(
			'pp-google-maps',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-google-maps' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-advanced-accordion',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-accordion' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-advanced-tabs',
			POWERPACK_ELEMENTS_URL . $path . 'pp-advanced-tabs' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-album',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-album' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-buttons',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-buttons' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-card-slider',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-card-slider' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-categories',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-categories' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_localize_script(
			'pp-categories',
			'ppCategoriesScript',
			[
				'ajax_url'         => admin_url( 'admin-ajax.php' ),
				'categories_nonce' => wp_create_nonce( 'pp-categories-widget-nonce' ),
			]
		);

		wp_register_script(
			'pp-carousel',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-carousel' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_localize_script(
			'pp-carousel',
			'ppCarouselScript',
			[
				/*
				 * Same msgid as the status element the carousel widgets print, so
				 * the announcement reads identically before and after the first
				 * slide change and translators only see the string once.
				 */
				/* translators: 1: current slide number, 2: total slides */
				'slide_status' => esc_html__( 'Showing Slide %1$s of %2$s', 'powerpack' ),
			]
		);

		wp_register_script(
			'pp-content-reveal',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-content-reveal' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-gravity-forms',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-gravity-forms' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-hotspots',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-hotspots' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-instafeed',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-instafeed' . $suffix . '.js',
			[
				'jquery',
				'pp-masonry',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-image-accordion',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-image-accordion' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-popup',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-popup' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-scroll-image',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-scroll-image' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-showcase',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-showcase' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-sitemap',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-sitemap' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-tabbed-gallery',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-tabbed-gallery' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-table',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-table' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-testimonials',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-testimonials' . $suffix . '.js',
			[
				'jquery',
				'pp-masonry',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-toggle',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-toggle' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-twitter',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-twitter' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-video',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-video' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-video-gallery',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-video-gallery' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-jquery-plugin',
			POWERPACK_ELEMENTS_URL . 'assets/js/jquery.plugin.js',
			[
				'jquery',
			],
			'1.0.0',
			true
		);

		wp_register_script(
			'pp-countdown-plugin',
			POWERPACK_ELEMENTS_URL . 'assets/lib/countdown/jquery.countdown' . $suffix . '.js',
			[
				'jquery',
			],
			'2.1.0',
			true
		);

		wp_register_script(
			'pp-countdown',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-countdown' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-image-comparison',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-image-comparison' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-toc',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-toc' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-marquee',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-marquee' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		$pp_toc_localize = apply_filters(
			'pp_toc_no_headings_text',
			[
				'no_headings_found' => __( 'No headings were found on this page.', 'powerpack' ),
			]
		);

		wp_localize_script( 'pp-toc', 'ppToc', $pp_toc_localize );

		wp_register_script(
			'pp-product-tabs',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-woo-product-tabs' . $suffix . '.js',
			[
				'jquery',
			],
			'1.0.0',
			true
		);

		wp_register_script(
			'jquery-smartmenu',
			POWERPACK_ELEMENTS_URL . 'assets/lib/smartmenu/jquery.smartmenus' . $suffix . '.js',
			[
				'jquery',
			],
			'1.1.1',
			true
		);

		wp_register_script(
			'pp-smartmenu-keyboard',
			POWERPACK_ELEMENTS_URL . 'assets/js/smartmenus-keyboard.js',
			[
				'jquery-smartmenu',
			],
			'1.0.0',
			true
		);

		wp_register_script(
			'pp-advanced-menu',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-advanced-menu' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-timeline',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-timeline' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_localize_script(
			'pp-timeline',
			'ppTimelineScript',
			[
				'ajax_url'       => admin_url( 'admin-ajax.php' ),
				'timeline_nonce' => wp_create_nonce( 'pp-posts-widget-nonce' ),
			]
		);

		wp_register_script(
			'tablesaw',
			POWERPACK_ELEMENTS_URL . 'assets/lib/tablesaw/tablesaw.jquery.js',
			[
				'jquery',
			],
			'3.0.3',
			true
		);

		wp_register_script(
			'tablesaw-init',
			POWERPACK_ELEMENTS_URL . 'assets/lib/tablesaw/tablesaw-init.js',
			[
				'jquery',
			],
			'3.0.3',
			true
		);

		wp_register_script(
			'tilt',
			POWERPACK_ELEMENTS_URL . 'assets/lib/tilt/tilt.jquery' . $suffix . '.js',
			[
				'jquery',
			],
			'1.1.19',
			true
		);

		wp_register_script(
			'pp-justified-gallery',
			POWERPACK_ELEMENTS_URL . 'assets/lib/justified-gallery/jquery.justifiedGallery' . $suffix . '.js',
			[
				'jquery',
			],
			'3.8.0',
			true
		);

		wp_register_script(
			'pp-masonry',
			POWERPACK_ELEMENTS_URL . $path . 'pp-masonry' . $suffix . '.js',
			array(
				'jquery',
			),
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-image-gallery',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-image-gallery' . $suffix . '.js',
			[
				'jquery',
				'pp-masonry',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-offcanvas-content',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-offcanvas-content' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'jquery-fancybox',
			POWERPACK_ELEMENTS_URL . 'assets/lib/fancybox/jquery.fancybox' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-tooltipster',
			POWERPACK_ELEMENTS_URL . 'assets/lib/tooltipster/tooltipster' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'twitter-widgets',
			POWERPACK_ELEMENTS_URL . $path . 'twitter-widgets' . $suffix . '.js',
			[
				'jquery',
			],
			'1.0.0',
			true
		);

		wp_register_script(
			'powerpack-pp-posts',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-posts' . $suffix . '.js',
			[
				'jquery',
				'pp-masonry',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_localize_script(
			'powerpack-pp-posts',
			'ppPostsScript',
			[
				'ajax_url'    => admin_url( 'admin-ajax.php' ),
				'posts_nonce' => wp_create_nonce( 'pp-posts-widget-nonce' ),
				'copied_text' => __( 'Copied', 'powerpack' ),
			]
		);

		wp_register_script(
			'powerpack-devices',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-devices' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-interactive-circle',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-interactive-circle' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-chartjs',
			POWERPACK_ELEMENTS_URL . 'assets/lib/chartjs/chart.umd.min.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-chart',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-charts' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-slide-menu',
			POWERPACK_ELEMENTS_URL . $path . 'pp-slide-menu' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		if ( is_pp_woocommerce() ) {
			wp_register_script(
				'pp-mini-cart',
				POWERPACK_ELEMENTS_URL . $path . 'frontend-woo-mini-cart' . $suffix . '.js',
				[
					'jquery',
				],
				POWERPACK_ELEMENTS_VER,
				true
			);

			wp_register_script(
				'pp-woo-my-account',
				POWERPACK_ELEMENTS_URL . $path . 'frontend-woo-my-account' . $suffix . '.js',
				[
					'jquery',
				],
				POWERPACK_ELEMENTS_VER,
				true
			);

			wp_register_script(
				'pp-woo-product',
				POWERPACK_ELEMENTS_URL . $path . 'frontend-woo-product' . $suffix . '.js',
				[
					'jquery',
				],
				POWERPACK_ELEMENTS_VER,
				true
			);

			wp_register_script(
				'pp-woo-add-to-cart',
				POWERPACK_ELEMENTS_URL . $path . 'frontend-woo-add-to-cart' . $suffix . '.js',
				[
					'jquery',
				],
				POWERPACK_ELEMENTS_VER,
				true
			);

			wp_register_script(
				'pp-woo-cart',
				POWERPACK_ELEMENTS_URL . $path . 'frontend-woo-cart' . $suffix . '.js',
				[
					'jquery',
				],
				POWERPACK_ELEMENTS_VER,
				true
			);

			wp_register_script(
				'pp-woo-add-to-cart-notification',
				POWERPACK_ELEMENTS_URL . $path . 'frontend-woo-add-to-cart-notification' . $suffix . '.js',
				[
					'jquery',
				],
				POWERPACK_ELEMENTS_VER,
				true
			);

			$pp_woo_localize = apply_filters(
				'pp_woo_elements_js_localize',
				[
					'ajax_url'          => admin_url( 'admin-ajax.php' ),
					'get_product_nonce' => wp_create_nonce( 'pp-product-nonce' ),
					'quick_view_nonce'  => wp_create_nonce( 'pp-qv-nonce' ),
					'add_cart_nonce'    => wp_create_nonce( 'pp-ac-nonce' ),
				]
			);
			wp_localize_script( 'pp-woo-product', 'pp_woo_products_script', $pp_woo_localize );
			wp_localize_script( 'pp-woo-add-to-cart', 'pp_woo_products_script', $pp_woo_localize );
			wp_localize_script( 'pp-woo-add-to-cart-notification', 'pp_woo_products_script', $pp_woo_localize );
		}

		wp_register_script(
			'particles',
			POWERPACK_ELEMENTS_URL . 'assets/lib/particles/particles.min.js',
			[
				'jquery',
			],
			'2.0.0',
			true
		);

		wp_register_script(
			'pp-three',
			POWERPACK_ELEMENTS_URL . 'assets/lib/three-vanta/three.min.js',
			[],
			'r134',
			true
		);

		wp_register_script(
			'vanta-birds',
			POWERPACK_ELEMENTS_URL . 'assets/lib/three-vanta/vanta.birds.min.js',
			[ 'pp-three' ],
			'0.5.24',
			true
		);

		wp_register_script(
			'vanta-dots',
			POWERPACK_ELEMENTS_URL . 'assets/lib/three-vanta/vanta.dots.min.js',
			[ 'pp-three' ],
			'0.5.24',
			true
		);

		wp_register_script(
			'vanta-fog',
			POWERPACK_ELEMENTS_URL . 'assets/lib/three-vanta/vanta.fog.min.js',
			[ 'pp-three' ],
			'0.5.24',
			true
		);

		wp_register_script(
			'vanta-net',
			POWERPACK_ELEMENTS_URL . 'assets/lib/three-vanta/vanta.net.min.js',
			[ 'pp-three' ],
			'0.5.24',
			true
		);

		wp_register_script(
			'vanta-waves',
			POWERPACK_ELEMENTS_URL . 'assets/lib/three-vanta/vanta.waves.min.js',
			[ 'pp-three' ],
			'0.5.24',
			true
		);

		wp_register_script(
			'pp-bg-effects',
			POWERPACK_ELEMENTS_URL . $path . 'pp-bg-effects' . $suffix . '.js',
			[
				'jquery',
			],
			'1.0.0',
			true
		);

		wp_register_script(
			'pp-custom-cursor',
			POWERPACK_ELEMENTS_URL . $path . 'pp-custom-cursor' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-wrapper-link',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-wrapper-link' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		wp_register_script(
			'pp-elements-tooltip',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-tooltip' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);


		wp_register_script(
			'pp-animated-gradient-bg',
			POWERPACK_ELEMENTS_URL . $path . 'pp-gradient-bg-animation' . $suffix . '.js',
			[
				'jquery',
			],
			'1.0.0',
			true
		);

		wp_register_script(
			'pp-print-this',
			POWERPACK_ELEMENTS_URL . 'assets/lib/printThis/printThis' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		// Event Calendar Widget.
		wp_register_script(
			'fullcalendar',
			POWERPACK_ELEMENTS_URL . 'assets/lib/fullcalendar/index.global' . $suffix . '.js',
			[
				'jquery',
			],
			'6.1.19',
			true
		);

		wp_register_script(
			'pp-event-calendar',
			POWERPACK_ELEMENTS_URL . $path . 'frontend-event-calendar' . $suffix . '.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

		$pp_localize = apply_filters(
			'pp_elements_js_localize',
			[
				'ajax_url' => admin_url( 'admin-ajax.php' ),
			]
		);
		wp_localize_script( 'jquery', 'pp', $pp_localize );
	}

	/**
	 * Enqueue frontend styles
	 *
	 * @since 1.3.3
	 *
	 * @access public
	 */
	public function enqueue_frontend_styles() {
		$debug_suffix     = ( PP_Helper::is_script_debug() ) ? '' : '.min';
		$direction_suffix = is_rtl() ? '-rtl' : '';
		$suffix           = $direction_suffix . $debug_suffix;
		$path             = ( PP_Helper::is_script_debug() ) ? 'assets/css/' : 'assets/css/min/';

		/* wp_enqueue_style(
			'powerpack-frontend',
			POWERPACK_ELEMENTS_URL . $path . 'frontend' . $suffix . '.css',
			[],
			POWERPACK_ELEMENTS_VER
		); */

		if ( class_exists( 'GFCommon' ) && \Elementor\Plugin::$instance->preview->is_preview_mode() && PP_Helper::is_widget_active( 'Gravity_Forms' ) ) {
			/**
			 * On the frontend the widget stylesheet is enqueued from the page assets, so it is
			 * printed in the head, while Gravity Forms prints its theme stylesheets where the
			 * form is rendered. Enqueue the widget stylesheet before the Gravity Forms assets
			 * below so that the editor preview keeps the same order, otherwise the widget
			 * stylesheet is only enqueued while the widget renders - after the Gravity Forms
			 * stylesheets - and rules of equal specificity resolve the other way around.
			 */
			wp_enqueue_style( 'widget-pp-gravity-forms' );

			$gf_forms = \RGFormsModel::get_forms( null, 'title' );
			foreach ( $gf_forms as $form ) {
				if ( '0' !== $form->id ) {
					wp_enqueue_script( 'gform_gravityforms' );
					gravity_form_enqueue_scripts( $form->id );
				}
			}
		}

		/* if ( class_exists( '\Ninja_Forms' ) && class_exists( '\NF_Display_Render' ) ) {
			add_action(
				'elementor/preview/enqueue_styles',
				function () {
					ob_start();
					\NF_Display_Render::localize( 0 );
					ob_clean();

					wp_add_inline_script( 'nf-front-end', 'var nfForms = nfForms || [];' );
				}
			);
		} */

		if ( function_exists( 'wpforms' ) ) {
			wpforms()->frontend->assets_css();
		}
	}

	/**
	 * Enqueue frontend scripts
	 *
	 * @since 1.3.3
	 *
	 * @access public
	 */
	public function enqueue_frontend_scripts() {
	}

	/**
	 * Enqueue editor styles
	 *
	 * @since 1.3.3
	 *
	 * @access public
	 */
	public function enqueue_editor_styles() {
		wp_enqueue_style(
			'powerpack-icons',
			POWERPACK_ELEMENTS_URL . 'assets/lib/ppicons/css/powerpack-icons.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_enqueue_style(
			'powerpack-editor',
			POWERPACK_ELEMENTS_URL . 'assets/css/editor.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		wp_enqueue_style( 'pp-hamburgers' );
	}

	/**
	 * Enqueue editor scripts
	 *
	 * @since 1.3.3
	 *
	 * @access public
	 */
	public function enqueue_editor_scripts() {
		wp_enqueue_script(
			'powerpack-editor',
			POWERPACK_ELEMENTS_URL . 'assets/js/editor.js',
			[
				'jquery',
			],
			POWERPACK_ELEMENTS_VER,
			true
		);

	}

	/**
	 * Enqueue preview styles
	 *
	 * @since 1.3.8
	 *
	 * @access public
	 */
	public function enqueue_editor_preview_styles() {
		wp_enqueue_style(
			'powerpack-editor',
			POWERPACK_ELEMENTS_URL . 'assets/css/editor.css',
			[],
			POWERPACK_ELEMENTS_VER
		);

		if ( is_pp_woocommerce() ) {
			wp_enqueue_style( 'pp-woocommerce' );
		}
		wp_enqueue_style( 'pp-hamburgers' );
		wp_enqueue_style( 'tablesaw' );
		wp_enqueue_style( 'fancybox' );

		if ( function_exists( 'wpFluentForm' ) ) {
			wp_enqueue_style(
				'fluent-form-styles',
				WP_PLUGIN_URL . '/fluentform/public/css/fluent-forms-public.css',
				[],
				FLUENTFORM_VERSION
			);

			wp_enqueue_style(
				'fluentform-public-default',
				WP_PLUGIN_URL . '/fluentform/public/css/fluentform-public-default.css',
				[],
				FLUENTFORM_VERSION
			);
		}

		$extensions         = function_exists( 'pp_get_enabled_extensions' ) ? pp_get_enabled_extensions() : get_option( 'pp_elementor_extensions' );
		$background_effects = ( is_array( $extensions ) && in_array( 'pp-background-effects', $extensions ) );

		if ( $background_effects ) {
			wp_enqueue_script( 'particles' );
			wp_enqueue_script( 'vanta-birds' );
			wp_enqueue_script( 'vanta-dots' );
			wp_enqueue_script( 'vanta-fog' );
			wp_enqueue_script( 'vanta-net' );
			wp_enqueue_script( 'vanta-waves' );
		}
	}

	/**
	 * Register Group Controls
	 *
	 * @since 1.1.4
	 */
	public function include_group_controls() {
		// Include Control Groups
		require POWERPACK_ELEMENTS_PATH . 'includes/controls/groups/transition.php';
		require POWERPACK_ELEMENTS_PATH . 'includes/controls/groups/toc_typo_control.php';

		// Add Control Groups
		\Elementor\Plugin::instance()->controls_manager->add_group_control( 'pp-transition', new Group_Control_Transition() );
		\Elementor\Plugin::instance()->controls_manager->add_group_control( 'pp-toc-typography-control', new Group_Control_Toc() );
	}

	/**
	 * Register Controls
	 *
	 * @since 2.0.0
	 *
	 * @access private
	 */
	public function register_controls() {

		// Include Controls
		require POWERPACK_ELEMENTS_PATH . 'includes/controls/query.php';

		// Register Controls
		//\Elementor\Plugin::instance()->controls_manager->register_control( 'pp-query', new Control_Query() );

		\Elementor\Plugin::instance()->controls_manager->register( new Control_Query() );
	}

	public function elementor_init() {
		$this->includes();

		$this->modules_manager     = new Modules_Manager();
		$this->_extensions_manager = new Extensions_Manager();

		if ( empty( $this->_settings ) && class_exists( 'PowerpackElements\\Classes\\PP_Admin_Settings' ) ) {
			$this->_settings = Classes\PP_Admin_Settings::get_settings();
		}
	}

	/**
	 * Register Elementor widget category
	 *
	 * @since 2.7.7
	 * @access public
	 *
	 * @param ElementorElements_Manager $manager Elements manager.
	 */
	public function register_category( $manager ) {
		$title = 'PowerPack Elements';
		if ( ! empty( $this->_settings ) && isset( $this->_settings['admin_label'] ) ) {
			$title = ! empty( $this->_settings['admin_label'] ) ? $this->_settings['admin_label'] : $title;
		}

		// Add element category in panel
		$manager->add_category(
			'powerpack-elements', // This is the name of your addon's category and will be used to group your widgets/elements in the Edit sidebar pane!
			[
				'title' => $title, // The title of your modules category - keep it simple and short!
				'icon'  => 'font',
			],
			1
		);

		$label = Classes\PP_Admin_Settings::get_admin_label();

		/*
		 * The store widgets sit in their own category rather than in the one
		 * above, which otherwise mixes them in with every content and media
		 * widget the plugin ships.
		 */
		$manager->add_category(
			'powerpack-woocommerce', // This is the name of your addon's category and will be used to group your widgets/elements in the Edit sidebar pane!
			[
				/* translators: %s: White label plugin name. */
				'title' => sprintf( esc_html__( '%s - WooCommerce', 'powerpack' ), $label ),
				'icon'  => 'font',
			],
			1
		);

		/*
		 * The builder widgets are separated from the ones above because they
		 * only render against a product in context, so they belong in a Single
		 * Product or Product Archive template and nowhere else. Nothing stops
		 * them being dropped on an ordinary page, so the category name is what
		 * tells the user where they are meant to go. The category is registered
		 * unconditionally: Elementor drops a category with no widgets in it, so
		 * this one disappears on its own when the builder is switched off.
		 */
		$manager->add_category(
			'powerpack-woocommerce-builder',
			[
				/* translators: %s: White label plugin name. */
				'title' => sprintf( esc_html__( '%s - WooCommerce Builder', 'powerpack' ), $label ),
				'icon'  => 'font',
			],
			1
		);
	}

	protected function add_actions() {
		add_action( 'elementor/init', [ $this, 'elementor_init' ] );
		add_action( 'elementor/elements/categories_registered', [ $this, 'register_category' ] );

		add_action( 'elementor/controls/register', [ $this, 'register_controls' ] );
		add_action( 'elementor/controls/register', [ $this, 'include_group_controls' ] );

		add_action( 'wp_enqueue_scripts', [ $this, 'register_style_scripts' ] );
		add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'register_style_scripts' ] );
		add_action( 'elementor/frontend/before_enqueue_scripts', [ $this, 'register_style_scripts' ] );

		add_action( 'elementor/editor/after_enqueue_scripts', [ $this, 'enqueue_editor_scripts' ] );
		add_action( 'elementor/editor/after_enqueue_styles', [ $this, 'enqueue_editor_styles' ] );

		add_action( 'elementor/preview/enqueue_styles', [ $this, 'enqueue_editor_preview_styles' ] );

		add_action( 'elementor/frontend/after_register_scripts', [ $this, 'enqueue_frontend_scripts' ] );
		add_action( 'elementor/frontend/after_enqueue_styles', [ $this, 'enqueue_frontend_styles' ] );
	}

	/**
	 * Plugin constructor.
	 */
	private function __construct() {
		spl_autoload_register( [ $this, 'autoload' ] );

		$this->add_actions();
	}

}

if ( ! defined( 'POWERPACK_ELEMENTS_TESTS' ) ) {
	// In tests we run the instance manually.
	Powerpackplugin::instance();
}
