initNotices();
    }
    public static function getInstance()
    {
        if (is_null(self::$instance))
            self::$instance = new AdminNoticesController();
        return self::$instance;
    }
    public static function resetAllNotices()
    {
        Notices::resetNotices();
    }
		// Notices no longer in use.
		public static function resetOldNotices()
		{
			Notices::removeNoticeByID('MSG_FEATURE_SMARTCROP');
      Notices::removeNoticeByID('MSG_FEATURE_HEIC');
		}
    /** Triggered when plugin is activated */
    public static function resetCompatNotice()
    {
        Notices::removeNoticeByID('MSG_COMPAT');
    }
    public static function resetAPINotices()
    {
        Notices::removeNoticeByID('MSG_NO_APIKEY');
        Notices::removeNoticeByID('MSG_NO_APIKEY_REPEAT');
        Notices::removeNoticeByID('MSG_NO_APIKEY_REPEAT_LONG');
    }
    public static function resetQuotaNotices()
    {
        Notices::removeNoticeByID('MSG_UPGRADE_MONTH');
        Notices::removeNoticeByID('MSG_UPGRADE_BULK');
        Notices::removeNoticeBYID('MSG_QUOTA_REACHED');
    }
    public static function resetIntegrationNotices()
    {
        Notices::removeNoticeByID('MSG_INTEGRATION_NGGALLERY');
    }
    public static function resetLegacyNotice()
    {
        Notices::removeNoticeByID('MSG_CONVERT_LEGACY');
    }
    public function displayNotices()
    {
        if (! \wpSPIO()->env()->is_screen_to_use)
        {
            if(get_current_screen()->base !== 'dashboard') // ugly exception for dashboard.
                return; // suppress all when not our screen.
        }
        $access = AccessModel::getInstance();
        $screen = get_current_screen();
        $screen_id = \wpSPIO()->env()->screen_id;
        $noticeControl = Notices::getInstance();
        $noticeControl->loadIcons(array(
            'normal' => '
',
            'success' => '
',
            'warning' => '
',
            'error' => '
',
        ));
        if ($noticeControl->countNotices() > 0)
        {
            $notices = $noticeControl->getNoticesForDisplay();
            if (count($notices) > 0)
            {
                \wpSPIO()->load_style('shortpixel-notices');
								\wpSPIO()->load_style('notices-module');
                foreach($notices as $notice)
                {
                    if ($notice->checkScreen($screen_id) === false)
                    {
                        continue;
                    }
                    elseif ($access->noticeIsAllowed($notice))
                    {
                        echo $notice->getForDisplay();
                    }
                    else
                    {
                        continue;
                    }
                    // @Todo change this to new keys
                    if ($notice->getID() == 'MSG_QUOTA_REACHED' || $notice->getID() == 'MSG_UPGRADE_MONTH') //|| $notice->getID() == AdminNoticesController::MSG_UPGRADE_BULK
                    {
                        // @todo check if this is still needed.
                        wp_enqueue_script('jquery.knob.min.js');
                        wp_enqueue_script('shortpixel');
                    }
                }
            }
        }
        $noticeControl->update(); // puts views, and updates
    }
    /* General function to check on Hook for admin notices if there is something to show globally */
    public function check_admin_notices()
    {
        if (! \wpSPIO()->env()->is_screen_to_use)
        {
            if(get_current_screen()->base !== 'dashboard') // ugly exception for dashboard.
                return; // suppress all when not our screen.
        }
       $this->loadNotices();
    }
    protected function initNotices()
    {
        foreach($this->definedNotices as $className)
        {
            $ns = '\ShortPixel\Model\AdminNotices\\' . $className;
            $class = new $ns();
            $this->adminNotices[$class->getKey()] = $class;
        }
    }
		protected function loadNotices()
		{
			 foreach($this->adminNotices as $key => $class)
			 {
				  $class->load();
					$this->doRemoteNotices();
			 }
		}
    public function getNoticeByKey($key)
    {
        if (isset($this->adminNotices[$key]))
        {
            return $this->adminNotices[$key];
        }
        else {
            return false;
        }
    }
    public function getAllNotices()
    {
        return $this->adminNotices;
    }
    // Called by MediaLibraryModel
    public function invokeLegacyNotice()
    {
        $noticeModel = $this->getNoticeByKey('MSG_CONVERT_LEGACY');
        if (! $noticeModel->isDismissed())
        {
            $noticeModel->addManual();
        }
    }
    protected function doRemoteNotices()
    {
        $notices = $this->get_remote_notices();
        if ($notices == false)
            return;
        foreach($notices as $remoteNotice)
        {
            if (! isset($remoteNotice->id) && ! isset($remoteNotice->message))
                return;
            if (! isset($remoteNotice->type))
                $remoteNotice->type = 'notice';
            $message = esc_html($remoteNotice->message);
            $id = sanitize_text_field($remoteNotice->id);
            $noticeController = Notices::getInstance();
            $noticeObj = $noticeController->getNoticeByID($id);
            // not added to system yet
            if ($noticeObj === false)
            {
                switch ($remoteNotice->type)
                {
                    case 'warning':
                        $new_notice = Notices::addWarning($message);
                        break;
                    case 'error':
                        $new_notice = Notices::addError($message);
                        break;
                    case 'notice':
                    default:
                        $new_notice = Notices::addNormal($message);
                        break;
                }
                Notices::makePersistent($new_notice, $id, MONTH_IN_SECONDS);
            }
        }
    }
    public function proposeUpgradePopup() {
        $view = new ViewController();
        $view->loadView('snippets/part-upgrade-options');
    }
    public function proposeUpgradeRemote()
    {
        //$stats = $this->countAllIfNeeded($this->_settings->currentStats, 300);
        $statsController = StatsController::getInstance();
        $apiKeyController = ApiKeyController::getInstance();
        $settings = \wpSPIO()->settings();
        $webpActive = ($settings->createWebp) ? true : false;
        $avifActive =  ($settings->createAvif) ? true : false;
        $args = array(
            'method' => 'POST',
            'timeout' => 10,
            'redirection' => 5,
            'httpversion' => '1.0',
            'blocking' => true,
            'headers' => array(),
            'body' => array("params" => json_encode(array(
                'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
                'key' => $apiKeyController->forceGetApiKey(),
                'm1' => $statsController->find('period', 'months', '1'),
                'm2' => $statsController->find('period', 'months', '2'),
                'm3' => $statsController->find('period', 'months', '3'),
                'm4' => $statsController->find('period', 'months', '4'),
                'filesTodo' => $statsController->totalImagesToOptimize(),
                'estimated' => $settings->optimizeUnlisted || $settings->optimizeRetina ? 'true' : 'false',
                'webp' => $webpActive,
                'avif' => $avifActive,
                /* */
                'iconsUrl' => base64_encode(wpSPIO()->plugin_url('res/img'))
            ))),
            'cookies' => array()
        );
        $proposal = wp_remote_post("https://shortpixel.com/propose-upgrade-frag", $args);
        if(is_wp_error( $proposal )) {
            $proposal = array('body' => __('Error. Could not contact ShortPixel server for proposal', 'shortpixel-image-optimiser'));
        }
        die( $proposal['body'] );
    }
    private function get_remote_notices()
    {
        $transient_name = 'shortpixel_remote_notice';
        $transient_duration = DAY_IN_SECONDS;
        if (\wpSPIO()->env()->is_debug)
            $transient_duration = 30;
        $keyControl = new apiKeyController();
        //$keyControl->loadKey();
        $notices = get_transient($transient_name);
        $url = $this->remote_message_endpoint;
        $url = add_query_arg(array(  // has url
            'key' => $keyControl->forceGetApiKey(),
            'version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
            'target' => 3,
        ), $url);
        if ( $notices === false  ) {
            $notices_response = wp_safe_remote_request( $url );
            $content = false;
            if (! is_wp_error( $notices_response ) )
            {
                $notices = json_decode($notices_response['body']);
                if (! is_array($notices))
                    $notices = false;
                // Save transient anywhere to prevent over-asking when nothing good is there.
                set_transient( $transient_name, $notices, $transient_duration );
            }
            else
            {
                set_transient( $transient_name, false, $transient_duration );
            }
        }
        return $notices;
    }
    public function pluginUpdateMessage($data, $response)
    {
        //    $message = $this->getPluginUpdateMessage($plugin['new_version']);
        $message = $this->get_update_notice($data, $response);
        if( $message !== false && strlen(trim($message)) > 0) {
            $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
            printf(
                '