/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2021 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jboss.installer.core;

import org.jboss.installer.actions.InstallerAction;

import javax.swing.JComponent;
import javax.swing.JPanel;

/**
 * Represents a screen in Installer.
 *
 * During transition between screens, callback methods will be executed on {@code Screen} in following order:
 *  <ul>
 *      <li>{@link Screen#load(InstallationData)} - before the content of {@link Screen#getContent()} is displayed</li>
 *      <li>{@link Screen#getPostLoadAction(InstallationData)} - right after the content of {@link Screen#getContent()} is displayed</li>
 *      <li>{@link Screen#validate()} - before current {@code Screen} is submitted</li>
 *      <li>{@link Screen#record(InstallationData)} - after validation, before next {@code Screen} is loaded</li>
 *  </ul>
 */
public interface Screen {

    String getTitle();

    String getSideNavName();

    String getName();

    JPanel getContent();

    boolean isActive();

    void setActive(boolean flag);

    Screen getParent();

    /**
     * read data from {@link InstallationData} needed for this Screen. Should not change {@code InstallationData} state.
     *
     * @param installationData
     */
    default void load(InstallationData installationData) {
        // do nothing
    }
    default void load(InstallationData installationData, ScreenManager screenManager) {
        load(installationData);
    }

        /**
         * gets an {@link InstallerAction} to be executed when the Screen is loaded. The action will be executed in separate thread.
         *
         * @param installationData
         * @return
         */
    default InstallerAction getPostLoadAction(InstallationData installationData) {
        return InstallerAction.EMPTY;
    }

    /**
     * called after the screen is submitted, but before validation
     *
     * @return true if OK to process, false otherwise
     */
    default boolean prevalidate() {
        return true;
    }

    /**
     * validate the state of {@code Screen} before it is submitted
     *
     * @return
     */
    default ValidationResult validate() {
        return ValidationResult.ok();
    }

    /**
     * update {@link InstallationData} with values from {@code Screen}.
     *
     * @param installationData
     */
    default void record(InstallationData installationData) {
        // do nothing
    }

    default void record(InstallationData installationData, ScreenManager screenManager) {
        record(installationData);
    }

    /**
     * rolls back {@link InstallationData} after going back to previous {@code Screen}.
     *
     * @param installationData
     */
    default void rollback(InstallationData installationData) {
        // do nothing
    }

    /**
     * decides if the user is allowed to return to a previous screen after this {@code Screen} is loaded
     *
     * @return
     */
    default boolean isReversible() {
        return true;
    }

    /**
     * returns a screen's component that should obtain the focus when switching to a new screen.
     *
     * @return component that should request focus or null if the focus should remain with the nav panel
     */
    default JComponent getDefaultFocusComponent() {
        return null;
    }
}
