/*
 * 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.
 */

/*
 * @author Paul Smith &lt;psmith@apache.org&gt;
 *
 */
package org.apache.log4j.chainsaw.components.tabbedpane;

import com.owlike.genson.Genson;
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;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;


/**
 * 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);
            }
        }
    }
}
