<?php
namespace TotalTheme;

defined( 'ABSPATH' ) || exit;

/**
 * Initialize Theme.
 *
 * @package TotalTheme
 * @version 5.5
 */
final class Initialize {

	/**
	 * Class instance.
	 */
	private static $instance;

	/**
	 * Create or retrieve the class instance.
	 */
	public static function instance() {
		if ( is_null( static::$instance ) ) {
			static::$instance = new self();
		}
		return static::$instance;
	}

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->global_functionality();
		$this->admin_functionality();
		$this->public_functionality();
		$this->init_hooks();
	}

	/**
	 * Global functionality.
	 */
	public function global_functionality() {
		Color_Scheme::instance();

		/*** Always include ***/

		// Core.
		require_once WPEX_INC_DIR . 'updates/after-update.php';
		require_once WPEX_INC_DIR . 'functions/deprecated.php';
		require_once WPEX_INC_DIR . 'functions/theme-mods.php';
		require_once WPEX_INC_DIR . 'functions/core-functions.php';
		require_once WPEX_INC_DIR . 'functions/conditionals.php';
		require_once WPEX_INC_DIR . 'functions/svgs.php';
		require_once WPEX_INC_DIR . 'functions/css-utility.php';
		require_once WPEX_INC_DIR . 'functions/parsers.php';
		require_once WPEX_INC_DIR . 'functions/sanitization-functions.php';
		require_once WPEX_INC_DIR . 'functions/arrays.php';
		require_once WPEX_INC_DIR . 'functions/translations.php';
		require_once WPEX_INC_DIR . 'functions/template-parts.php';
		require_once WPEX_INC_DIR . 'functions/wp-fallbacks.php';
		require_once WPEX_INC_DIR . 'functions/post-types-branding.php';
		require_once WPEX_INC_DIR . 'functions/recommended-plugins.php';
		require_once WPEX_INC_DIR . 'functions/fonts.php';
		require_once WPEX_INC_DIR . 'functions/post-thumbnails.php';
		require_once WPEX_INC_DIR . 'functions/overlays.php';
		require_once WPEX_INC_DIR . 'functions/shape-dividers.php';
		require_once WPEX_INC_DIR . 'functions/aria-labels.php';
		require_once WPEX_INC_DIR . 'cards/card-functions.php';

		// Actions.
		new Register_AJAX_Callbacks();
		require_once WPEX_INC_DIR . 'functions/wp-actions/register-widget-areas.php';
		add_action( 'after_switch_theme'    , __NAMESPACE__ . '\\Actions\\After_Switch_Theme::callback' );

		// Filters.
		add_filter( 'http_request_args'     , __NAMESPACE__ . '\\Filters\\Http_Request_Args::callback', 5, 2 );
		add_filter( 'kses_allowed_protocols', __NAMESPACE__ . '\\Filters\\Kses_Allowed_Protocols::callback' );
		add_filter( 'wp_get_attachment_url' , __NAMESPACE__ . '\\Filters\\WP_Get_Attachment_Url::callback' );

		// Theme builder.
		require_once WPEX_INC_DIR . 'theme-builder/functions.php'; // !! must load here !!
		require_once WPEX_INC_DIR . 'theme-builder/theme-builder.php';

		/** Maybe include */

		// Header builder.
		if ( get_theme_mod( 'header_builder_enable', true ) ) {
			require_once WPEX_INC_DIR . 'theme-builder/header-builder.php';
		}

		// Footer builder.
		if ( get_theme_mod( 'footer_builder_enable', true ) ) {
			require_once WPEX_INC_DIR . 'theme-builder/footer-builder.php';
		}

		// Error 404 Page.
		Error_404::instance();

		// Page animations.
		if ( get_theme_mod( 'page_animations_enable', true ) ) {
			Page_Animations::instance();
		}

		// WP Header Image support.
		if ( get_theme_mod( 'header_image_enable', false ) ) {
			WP_Custom_Header::instance();
		}

		// Custom output for WP gallery.
		if ( wpex_custom_wp_gallery_supported() ) {
			Post_Gallery::instance();
		}

		// Under Construction.
		if ( get_theme_mod( 'under_construction_enable', true ) ) {
			Under_Construction::instance();
		}

		// Helper class for disabling Google services.
		if ( wpex_disable_google_services() ) {
			Disable_Google_Services::instance();
		}

		// Widget Block editor.
		Widgets\Block_Editor::instance();

		// Custom Favicons panel and output.
		if ( get_theme_mod( 'favicons_enable', true ) ) {
			Favicons::instance();
		}

		// Custom login page.
		if ( get_theme_mod( 'custom_admin_login_enable', true ) ) {
			Custom_Login::instance();
		}

		// Custom actions panel.
		if ( get_theme_mod( 'custom_actions_enable', true ) ) {
			Custom_Actions::instance();
		}

		// Helper class for removing cpt slugs.
		if ( get_theme_mod( 'remove_posttype_slugs', false ) ) {
			Remove_Cpt_Slugs::instance();
		}

		/** 3rd Party Integrations **/
		Integrations::instance();

		/* These Classes must Load last */

		// Image sizes panel and registration.
		if ( get_theme_mod( 'image_sizes_enable', true ) ) {
			Image_Sizes::instance();
		}

		// Customizer utility class and theme settings array.
		require_once WPEX_INC_DIR . 'customizer/class-wpex-customizer.php';

		// Typography Customizer panel, settings and front-end output.
		if ( get_theme_mod( 'typography_enable', true ) ) {
			Typography::instance();
		}

	}

	/**
	 * Admin functionality.
	 */
	public function admin_functionality() {
		$this->health_checks();

		// Main Theme Panel.
		Admin\Theme_Panel::instance();

		// Provide auto updates for the theme.
		if ( get_theme_mod( 'auto_updates', true ) ) {
			Updates\Theme_Updater::instance();
		}

		// Plugin update notifications.
		if ( apply_filters( 'wpex_has_bundled_plugin_update_notices', true ) ) {
			Updates\Plugin_Updater::instance();
		}

		// Post type editor class.
		if ( get_theme_mod( 'post_type_admin_settings', true ) ) {
			Admin\Cpt_Settings::instance();
		}

		// Import/Export panel.
		if ( get_theme_mod( 'import_export_enable', true ) ) {
			Admin\Import_Export::instance();
		}

		// Theme license panel.
		if ( apply_filters( 'wpex_show_license_panel', true ) ) {
			Admin\License_Panel::instance();
		}

		// Mce format styles.
		Editor\Mce_Formats::instance();

		// Accessibility Panel.
		if ( apply_filters( 'wpex_accessibility_panel', true ) ) {
			Accessibility\Admin_Panel::instance();
		}

		// Custom styles for the WP editor (classic & gutenberg).
		if ( get_theme_mod( 'editor_styles_enable', true ) ) {
			Editor\Editor_Styles::instance();
		}

		// Display Thumbnails in the WP admin posts list view.
		Admin\Dashboard_Thumbnails::instance();

		// Register & Enqueue scripts for use in the admin.
		Admin\Scripts::instance();
	}

	/**
	 * Public/Frontend functionality.
	 */
	public function public_functionality() {

		// Include core functions.
		// @todo move to classes so they are only loaded when needed via autoloader.
		require_once WPEX_INC_DIR . 'functions/frontend/html-class.php';
		require_once WPEX_INC_DIR . 'functions/frontend/google-analytics.php';
		require_once WPEX_INC_DIR . 'functions/frontend/layouts.php';
		require_once WPEX_INC_DIR . 'functions/frontend/breadcrumbs.php';
		require_once WPEX_INC_DIR . 'functions/frontend/wpex-the-content.php';
		require_once WPEX_INC_DIR . 'functions/frontend/head-meta-tags.php';
		require_once WPEX_INC_DIR . 'functions/frontend/schema-markup.php';
		require_once WPEX_INC_DIR . 'functions/frontend/social-share.php';
		require_once WPEX_INC_DIR . 'functions/frontend/videos.php';
		require_once WPEX_INC_DIR . 'functions/frontend/audio.php';
		require_once WPEX_INC_DIR . 'functions/frontend/author.php';
		require_once WPEX_INC_DIR . 'functions/frontend/post-media.php';
		require_once WPEX_INC_DIR . 'functions/frontend/excerpts.php';
		require_once WPEX_INC_DIR . 'functions/frontend/togglebar.php';
		require_once WPEX_INC_DIR . 'functions/frontend/header.php';
		require_once WPEX_INC_DIR . 'functions/frontend/header-menu.php';
		require_once WPEX_INC_DIR . 'functions/frontend/title.php';
		require_once WPEX_INC_DIR . 'functions/frontend/post-slider.php';
		require_once WPEX_INC_DIR . 'functions/frontend/post-gallery.php';
		require_once WPEX_INC_DIR . 'functions/frontend/page-header.php';
		require_once WPEX_INC_DIR . 'functions/frontend/sidebar.php';
		require_once WPEX_INC_DIR . 'functions/frontend/footer-callout.php';
		require_once WPEX_INC_DIR . 'functions/frontend/footer.php';
		require_once WPEX_INC_DIR . 'functions/frontend/grids.php';
		require_once WPEX_INC_DIR . 'functions/frontend/page.php';
		require_once WPEX_INC_DIR . 'functions/frontend/archives.php';
		require_once WPEX_INC_DIR . 'functions/frontend/loop.php';
		require_once WPEX_INC_DIR . 'functions/frontend/blog.php';
		require_once WPEX_INC_DIR . 'functions/frontend/portfolio.php';
		require_once WPEX_INC_DIR . 'functions/frontend/staff.php';
		require_once WPEX_INC_DIR . 'functions/frontend/testimonials.php';
		require_once WPEX_INC_DIR . 'functions/frontend/cpt.php';
		require_once WPEX_INC_DIR . 'functions/frontend/search.php';
		require_once WPEX_INC_DIR . 'functions/frontend/star-rating.php';
		require_once WPEX_INC_DIR . 'functions/frontend/user-social-links.php';
		require_once WPEX_INC_DIR . 'functions/frontend/post-format-icons.php';
		require_once WPEX_INC_DIR . 'functions/frontend/local-scroll.php';

		// Actions
		add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\\Actions\\WP_Enqueue_Scripts::callback' );
		add_action( 'template_redirect', __NAMESPACE__ . '\\Actions\\Template_Redirect::callback' );
		add_action( 'pre_get_posts', __NAMESPACE__ . '\\Filters\\Pre_Get_Posts::callback' );

		// Filters
		add_filter( 'body_class', __NAMESPACE__ . '\\Filters\\Body_Class::callback' );
		add_filter( 'post_class', __NAMESPACE__ . '\\Filters\\Post_Class::callback', 10, 3 );
		add_filter( 'widget_tag_cloud_args', __NAMESPACE__ . '\\Filters\\Tag_Cloud_Args::callback' );
		add_filter( 'redirect_canonical', __NAMESPACE__ . '\\Filters\\Redirect_Canonical::callback' );
		add_filter( 'comment_form_fields', __NAMESPACE__ . '\\Filters\\Comment_Form_Fields::callback' );
		add_filter( 'the_author_posts_link', __NAMESPACE__ . '\\Filters\\The_Authors_Post_Link::callback' );
		add_filter( 'the_password_form', __NAMESPACE__ . '\\Filters\\The_Password_Form::callback' );
		add_filter( 'get_comment_author', __NAMESPACE__ . '\\Filters\\Get_Comment_Author::callback', 10, 2 );
		add_filter( 'widget_nav_menu_args', __NAMESPACE__ . '\\Filters\\Widget_Nav_Menu_Args::callback', 10, 4 );

		// Hook into wp filters.
		require_once WPEX_INC_DIR . 'functions/wp-filters/oembed.php';
		require_once WPEX_INC_DIR . 'functions/wp-filters/comments-link-scrollto-fix.php';
		require_once WPEX_INC_DIR . 'functions/wp-filters/next-previous-posts-exclude.php';
		require_once WPEX_INC_DIR . 'functions/wp-filters/widget-custom-classes.php';

		// Remove menu ID's for accessibility if enabled.
		if ( get_theme_mod( 'remove_menu_ids', false ) && apply_filters( 'wpex_accessibility_panel', true ) ) {
			require_once WPEX_INC_DIR . 'functions/wp-filters/accessibility-remove-menu-ids.php';
		}

		// Remove site emoji scripts.
		if ( get_theme_mod( 'remove_emoji_scripts_enable', true ) ) {
			remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
			remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
			remove_action( 'wp_print_styles', 'print_emoji_styles' );
			remove_action( 'admin_print_styles', 'print_emoji_styles' );
			remove_action( 'the_content', 'convert_smilies', 20 );
		}

		// Add a span around the WordPress category widgets for easier styling.
		if ( apply_filters( 'wpex_widget_counter_span', true ) ) {
			require_once WPEX_INC_DIR . 'functions/wp-filters/widget-add-span-to-count.php';
		}

		// Enable post thumbnail format icons.
		if ( get_theme_mod( 'thumbnail_format_icons', false ) ) {
			Thumbnail_Format_Icons::instance();
		}

		// Lightbox functions (must run after JS::register() )
		Lightbox::instance();

		// Load global fonts.
		Fonts\Global_Fonts::instance();

		// Custom site backgrounds.
		Site_Backgrounds::instance();

		// Theme breadcrumbs.
		require_once WPEX_INC_DIR . 'lib/wpex-breadcrumbs.php';

		// Outputs inline CSS for theme settings.
		Inline_CSS::instance();

		/*** Maybe include ***/

			// Advanced styles for various Customizer options.
			if ( apply_filters( 'wpex_generate_advanced_styles', true ) ) {
				Advanced_Styles::instance(); // can't hook directly into wpex_head_css cause it causes issues in Customizer.
			}

	}

	/**
	 * Registers health checks.
	 */
	public function health_checks() {
		$health_checks = array(
			new Health_Check\Header_Menu_Dropdown_SuperFish(),
			new Health_Check\Jquery_Easing(),
		);

		foreach ( $health_checks as $health_check ) {
			$health_check->register_test();
		}
	}

	/**
	 * Hook into actions and filters.
	 */
	public function init_hooks() {
		After_Setup_Theme::instance();
		add_action( 'after_setup_theme', __CLASS__ . '::hooks_actions', 10 );
		add_filter( 'woocommerce_create_pages', __CLASS__ . '::disable_woocommerce_create_pages' );
	}

	/**
	 * Runs on the after_setup_theme hook.
	 */
	public static function hooks_actions() {
		require_once WPEX_INC_DIR . 'functions/hooks/hooks.php';
		require_once WPEX_INC_DIR . 'functions/hooks/add-actions.php';
		require_once WPEX_INC_DIR . 'functions/hooks/remove-actions.php';
		require_once WPEX_INC_DIR . 'functions/hooks/partials.php';
	}

	/**
	 * Prevent Woocommerce from installing pages on installation.
	 */
	public static function disable_woocommerce_create_pages( $pages ) {
		if ( defined( 'WC_INSTALLING' ) && true === WC_INSTALLING ) {
			return array();
		}
		return $pages;
	}

}