package cn.ieclipse.smartim.console;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicButtonUI;

/**
 * Created by Jamling on 2017/7/3.
 */
public class ClosableTabHost extends JTabbedPane implements ChangeListener {
    private Insets insets = new Insets(0, 0, 0, 0);
    private Callback callback;

    public ClosableTabHost() {
        super(JTabbedPane.TOP);
        addChangeListener(this);
    }

    public ClosableTabHost(Callback callback) {
        this();
        setCallback(callback);
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    @Override
    public Border getBorder() {
        return BorderFactory.createEmptyBorder();
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        int index = getSelectedIndex();
        if (index >= 0) {
            setBackgroundAt(index, null);
        }
    }

    @Override
    public void insertTab(String title, Icon icon, Component component, String tip, int index) {
        super.insertTab(title, icon, component, tip, index);
        setTabComponentAt(index, createTab(title));
    }

    public Component createTab(String text) {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        JLabel label = new JLabel(text);
        label.setOpaque(false);
        panel.add(label);
        TabButton btn = new TabButton();
        panel.add(btn);
        panel.setBackground(Color.black);
        panel.setOpaque(false);
        return panel;
    }

    public void bling(final int index, String name) {
        if (index >= 0 && index < getTabCount() && index != getSelectedIndex()) {
            Component tab = getTabComponentAt(index);
            if (tab != null) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        setBackgroundAt(index, UIManager.getColor("TabbedPane.selected"));
                    }
                });
                new BlingTimer(tab, name).start();
            }
        }
    }

    private class BlingTimer extends Timer implements ActionListener {
        Component component;
        JLabel label;
        String src;
        Dimension d;
        int count = 4;

        public BlingTimer(Component tab, String name) {
            super(300, null);
            addActionListener(this);
            component = tab;
            if (component != null && component instanceof JPanel) {
                label = (JLabel)((JPanel)component).getComponent(0);
                src = label.getText();
                if (src == null || src.isEmpty()) {
                    src = name;
                }
                d = label.getSize();
                label.setPreferredSize(d);
            }
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                label.setText(count % 2 == 0 ? "" : src);
                count--;
                if (count <= 0) {
                    stop();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public void stop() {
            label.setText(src);
            super.stop();
        }
    }

    private class TabButton extends JButton implements ActionListener {
        public TabButton() {
            // super(SmartIcons.close);
            int size = 16;
            setPreferredSize(new Dimension(size, size));
            setToolTipText("close");
            // Make the button looks the same for all Laf's
            setUI(new BasicButtonUI());
            setOpaque(false);
            // Make it transparent
            setContentAreaFilled(false);
            // No need to be focusable
            setFocusable(false);
            setBorder(BorderFactory.createEmptyBorder());
            setBorderPainted(false);
            // Making nice rollover effect
            // we use the same listener for all buttons
            // addMouseListener(buttonMouseListener);
            setRolloverEnabled(true);
            // Close the proper tab by clicking the button
            addActionListener(this);
        }

        public void actionPerformed(ActionEvent e) {
            int i = indexOfTabComponent(getParent());
            if (i != -1) {
                if (callback != null) {
                    callback.removeTabAt(i);
                } else {
                    removeTabAt(i);
                }
            }
        }

        // we don't want to update UI for this button
        public void updateUI() {}

        // paint the cross
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g.create();
            // shift the image for pressed buttons
            if (getModel().isPressed()) {
                g2.translate(1, 1);
            }
            g2.setStroke(new BasicStroke(2));
            g2.setColor(Color.GRAY);
            if (getModel().isRollover()) {
                g2.setColor(Color.LIGHT_GRAY);
            }
            int delta = 5;
            g2.drawLine(delta, delta, getWidth() - delta, getHeight() - delta);
            g2.drawLine(getWidth() - delta, delta, delta, getHeight() - delta);
            g2.dispose();
        }
    }

    public interface Callback {
        void removeTabAt(int index);
    }
}