<?php defined('ABSPATH') OR die('Access denied! Install it on WordPress platform. It is a WordPress menu manager helper library. Simply include it on your plugins file.');
/**
 * Portable menu manager for Wordpress. This class can be used from any location to build WordPress menu easily. 
 * Just need to specify the folder for menu calback functions. Use muse define O365_WP_USE_LIBRARIES
 * constent to use this libraries.
 * HOW TO USE?
 * 1. Include this file to any of your plugins file. (Check result on your dashboard)
 * 2. Set directory where you want to store your callback function of each menu. Default is 'menu_cb' beside this file.
 */
if( ! class_exists('o365_Wp_Menu_Manager')):
    class o365_Wp_Menu_Manager
	{
        /**
         * @var Object This class uses single to pattern.
         */
        private static $instance = null;
        /**
         * 
         * @param string $cb_func_storage_dir Locaton, where callback function of menu will be stored. If no path provided, default location will be the 'menu_cb' dir beside this file.
         * @return Object 
         */
        public static function getInstance( $cb_func_storage_dir )
		{
            if( self::$instance === null ){
                self::$instance = new self( $cb_func_storage_dir );
            }
            return self::$instance;
        }
        /**
         * @param string $dir Directory name for callback functions.
         */
        public function __construct( $dir )
		{
            defined('O365_WP_MENU_MANAGER_CB_DIR') OR define('O365_WP_MENU_MANAGER_CB_DIR', $dir );
            /**
             * Make sure priority of this hook is before 10. 
             * Because other user may add submenu for this top lavel menu.
             */
            add_action('admin_menu', array( $this, 'register_admin_menu'), 8 );
            if ( is_multisite() ) {
				add_action( 'network_admin_menu', array( $this, 'register_admin_menu'), 8 );
			}
        }
        public function register_admin_menu()
		{
            // Add Top menu for this plugin
            $top_slug       = apply_filters('o365_menu_manager_top_slug','o365_settings');
            $cb_prefix      = apply_filters('o365_menu_manager_cb_func_prefix','o365_menu_');
            $permission     = apply_filters('o365_menu_manager_permission','administrator');
            $cb_function    = $cb_prefix . $top_slug;

            // Include callback function for top menu
            $cb_func_file = O365_WP_MENU_MANAGER_CB_DIR . $cb_function . '.php';
            if(file_exists($cb_func_file)) include_once $cb_func_file;
            add_menu_page(
                    apply_filters('o365_menu_manager_top_menu_title','o365 Menu Manager'),
                    apply_filters('o365_menu_manager_top_menu_level','Build Menu'),
                    $permission ,
                    $top_slug,
                    $cb_function ,
                    apply_filters('o365_menu_manager_top_menu_icon','dashicons-controls-repeat'),
                    apply_filters('o365_menu_manager_top_menu_priority',9.89));
            // Add other menus from filters
            $sub_menus = apply_filters('o365_menu_manager_menu_items',array());
            if( count( $sub_menus ) > 0 ){
				$top_slug_temp = "o365";
				 foreach( $sub_menus as $slug => $menu )
				 {
					if( $slug =="")
					{
						$cb = $cb_prefix .$top_slug_temp;
						$sub_menus_slug = $top_slug_temp;
					}
					else
					{
                    	$cb = $cb_prefix .$top_slug_temp."_". $slug;
						$sub_menus_slug = $top_slug_temp . '_' . $slug;
				 	}

                     // Include callback function for top menu
                    $cb_func_file = O365_WP_MENU_MANAGER_CB_DIR . $cb . '.php';
                    if(file_exists($cb_func_file)) include_once $cb_func_file;
                    add_submenu_page($top_slug, $menu[0], $menu[1], (isset($menu[2])?$menu[2]:$permission), $sub_menus_slug, $cb );
                }
            }
        }
    }
endif;
/**
 * Make suer this function is called after 'init' hook after priority 10  . 
 * Because other user will add filter to change some value adding init hook.
 */
add_action('init', function(){
    // Location, where menu cb funcion will be stored
    $dir = apply_filters('o365_menu_cb_func_dir', dirname(__FILE__) . '/menu_cb/');
    o365_Wp_Menu_Manager::getInstance( $dir );
}, 15 );
// Close of the file