/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you 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.apache.log4j.chainsaw.components.tabbedpane;

import com.owlike.genson.Genson;
import java.awt.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import javax.swing.*;
import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SettingsListener;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * The only reason this class is needed is because
 * of a stupid 'issue' with the JTabbedPane.
 * <p>
 * If the currently selected tab is the first tab,
 * and we insert a new tab at the front, then as
 * far as the JTabbedPane is concerned, NO STATE has
 * changed, as the currently selected tab index is still
 * the same (even though the TAB is different - go figure)
 * and therefore no ChangeEvent is generated and sent
 * to listeners.  Thanks very much Sun!
 * <p>
 * For more information on the issue:
 * http://developer.java.sun.com/developer/bugParade/bugs/4253819.html
 *
 * @author Paul Smith &lt;psmith@apache.org&gt;
 * @author Scott Deboy &lt;sdeboy@apache.org&gt;
 */
public class ChainsawTabbedPane extends JTabbedPane implements SettingsListener {
    private static Logger logger = LogManager.getLogger(ChainsawTabbedPane.class);
    public SavableTabSetting tabSetting;
    public static final String WELCOME_TAB = "Welcome";
    public static final String ZEROCONF = "Zeroconf";

    /**
     * Returns true if this TabbedPane has an instance of the WelcomePanel
     * in it
     *
     * @return true/false
     */
    public boolean containsWelcomePanel() {
        return indexOfTab("Welcome") > -1;
    }

    /**
     * Our custom implementation of inserting a new tab,
     * this method ALWAYS inserts it at the front because
     * we get an ArrayIndexOutOfBoundsException otherwise
     * under some JDK implementations.
     * <p>
     * This method also causes a fireStateChange() to be
     * called so that listeners get notified of the event.
     * See the class level comments for the reason why...
     *
     * @param name
     * @param component
     */
    public void addANewTab(String name, JComponent component, Icon icon, boolean switchToTab) {
        super.insertTab(name, icon, component, null, getTabCount());

        super.fireStateChanged();
        if (!"chainsaw-log".equals(name) && switchToTab) {
            EventQueue.invokeLater(() -> setSelectedTab(getTabCount() - 1));
        }
    }

    public void setSelectedTab(int index) {
        if (getTabCount() >= index) {
            setSelectedIndex(index);
        }

        getSelectedComponent().setVisible(true);
        getSelectedComponent().validate();
        super.fireStateChanged();
    }

    public void addANewTab(String name, JComponent component, Icon icon, String tooltip) {
        super.insertTab(name, icon, component, tooltip, getTabCount());
        super.fireStateChanged();
    }

    public void remove(Component component) {
        super.remove(component);
        super.fireStateChanged();
    }

    /**
     * Saves the state of the currently active tabs to an XML file.
     * Only considers the Welcome, Drag and Drop and chainsaw-log
     * panels as they are the panel which are always running. Saves
     * whether they are hidden or not....
     */
    public void saveSettings(SaveSettingsEvent event) {
        File file = new File(SettingsManager.getSettingsDirectory(), "tab-settings.json");

        int count = super.getTabCount();
        String title;

        SavableTabSetting setting = new SavableTabSetting();
        for (int i = 0; i < count; i++) {
            title = super.getTitleAt(i);
            switch (title) {
                case WELCOME_TAB:
                    setting.setWelcome(true);
                    break;
                case "chainsaw-log":
                    setting.setChainsawLog(true);
                    break;
                case ZEROCONF:
                    setting.setZeroconf(true);
                    break;
            }
        }

        Genson genson = new Genson();
        String serialize = genson.serialize(setting);

        try (FileWriter writer = new FileWriter(file)) {
            writer.write(serialize);
        } catch (Exception e) {
            logger.error("Could not write to tab-settings.json", e);
            try {
                Files.deleteIfExists(file.toPath());
            } catch (IOException ex) {
                logger.error("Could not clean up file tab-settings.json", ex);
            }
        }
    }

    /**
     * Loads the saved tab setting by reading the XML file.
     * If the file doesn't exist, all three panels should be
     * shown as the default setting....
     */
    public void loadSettings(LoadSettingsEvent event) {
        File file = new File(SettingsManager.getSettingsDirectory(), "tab-settings.json");
        Genson genson = new Genson();

        try {
            if (file.exists()) {
                String json = Files.readAllLines(file.toPath()).get(0);
                tabSetting = genson.deserialize(json, SavableTabSetting.class);
            } else {
                tabSetting = new SavableTabSetting();
                tabSetting.setWelcome(true);
                tabSetting.setChainsawLog(true);
                tabSetting.setZeroconf(true);
            }
        } catch (Exception e) {
            logger.error("Could not read from tab-settings.json", e);
            try {
                Files.deleteIfExists(file.toPath());
            } catch (IOException ex) {
                logger.error("Could not clean up file tab-settings.json", ex);
            }
        }
    }
}
