/*
 * Copyright (C) 2025-2026  Tim Zimmermann <tim@aglais.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.aglais.zms.ui.tab;

import org.aglais.zms.AglaisZMS;

import javax.swing.*;
import java.util.ResourceBundle;

/**
 * Tab interface that can contain multiple {@link SubTab}s
 */
public interface ISubTabbedTab extends ISavableTab {
    /**
     * Get the {@link JTabbedPane} containing {@link SubTab}s
     *
     * @return Tabbed pane containing subtabs
     */
    JTabbedPane getTabbedPane();

    /**
     * Get the {@link SubTab}s
     *
     * @return The subtabs
     */
    SubTab<?>[] getTabs();

    /**
     * Register all the {@link SubTab}s as returned by {@link #getTabs}
     */
    default void registerSubTabs() {
        SubTab<?>[] tabs = getTabs();
        SubTab<?> tab = getSelectedTab();

        // Register tabs if neccessary
        if (getTabbedPane().getTabCount() != tabs.length) {
            Tab.registerAll(getTabbedPane(), ResourceBundle.getBundle("ui"), tabs);
            SwingUtilities.updateComponentTreeUI(getTabbedPane());
        }

        if (tab != null)
            tab.show();
    }

    /**
     * Unregister all {@link SubTab}s
     */
    default void unregisterSubTabs() {
        SubTab<?> tab = getSelectedTab();
        if (tab != null)
            tab.hide();

        getTabbedPane().removeAll();
    }

    /**
     * Retrieves the currently selected sub-tab.
     * The returned sub-tab corresponds to the index retrieved from the associated tabbed pane
     * if it falls within the bounds of the available tabs.
     *
     * @return The currently selected {@link SubTab} instance, or {@code null} if no valid tab is selected.
     */
    private SubTab<?> getSelectedTab() {
        SubTab<?>[] tabs = getTabs();
        int index = getTabbedPane().getSelectedIndex();
        if (index >= 0 && index < tabs.length) {
            return tabs[index];
        }

        return null;
    }

    @Override
    default String getSaveTitle() {
        SubTab<?> tab = getSelectedTab();

        if (tab instanceof ISavableTab savableTab)
            return savableTab.getSaveTitle();
        return null;
    }

    @Override
    default boolean hasUnsavedChanges() {
        SubTab<?> tab = getSelectedTab();

        if (tab instanceof ISavableTab savableTab)
            return savableTab.hasUnsavedChanges();
        return false;
    }

    @Override
    default boolean saveChanges() {
        SubTab<?> tab = getSelectedTab();

        if (tab instanceof ISavableTab savableTab)
            return savableTab.saveChanges();
        return false;
    }

    @Override
    default void discardChanges() {
        SubTab<?> tab = getSelectedTab();

        if (tab instanceof ISavableTab savableTab)
            savableTab.discardChanges();
    }
}
