/*
 * Copyright 2011 gitblit.com.
 *
 * 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 com.gitblit.client;

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.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.plaf.basic.BasicButtonUI;

/**
 * Closable tab control.
 */
public class ClosableTabComponent extends JPanel {

	private static final long serialVersionUID = 1L;

	private static final MouseListener BUTTON_MOUSE_LISTENER = new MouseAdapter() {
		@Override
		public void mouseEntered(MouseEvent e) {
			Component component = e.getComponent();
			if (component instanceof AbstractButton) {
				AbstractButton button = (AbstractButton) component;
				button.setBorderPainted(true);
			}
		}

		@Override
		public void mouseExited(MouseEvent e) {
			Component component = e.getComponent();
			if (component instanceof AbstractButton) {
				AbstractButton button = (AbstractButton) component;
				button.setBorderPainted(false);
			}
		}
	};

	private final JTabbedPane pane;
	private final JLabel label;
	private final JButton button = new TabButton();

	private final CloseTabListener closeListener;

	public interface CloseTabListener {
		void closeTab(Component c);
	}

	public ClosableTabComponent(String title, ImageIcon icon, JTabbedPane pane,
			CloseTabListener closeListener) {
		super(new FlowLayout(FlowLayout.LEFT, 0, 0));
		this.closeListener = closeListener;

		if (pane == null) {
			throw new NullPointerException("TabbedPane is null");
		}
		this.pane = pane;
		setOpaque(false);
		label = new JLabel(title);
		if (icon != null) {
			label.setIcon(icon);
		}

		add(label);
		label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
		add(button);
		setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
	}

	private class TabButton extends JButton implements ActionListener {

		private static final long serialVersionUID = 1L;

		public TabButton() {
			int size = 17;
			setPreferredSize(new Dimension(size, size));
			setToolTipText("Close");
			setUI(new BasicButtonUI());
			setContentAreaFilled(false);
			setFocusable(false);
			setBorder(BorderFactory.createEtchedBorder());
			setBorderPainted(false);
			addMouseListener(BUTTON_MOUSE_LISTENER);
			setRolloverEnabled(true);
			addActionListener(this);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			int i = pane.indexOfTabComponent(ClosableTabComponent.this);
			Component c = pane.getComponentAt(i);
			if (i != -1) {
				pane.remove(i);
			}
			if (closeListener != null) {
				closeListener.closeTab(c);
			}
		}

		@Override
		public void updateUI() {
		}

		@Override
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			Graphics2D g2 = (Graphics2D) g;
			Stroke stroke = g2.getStroke();
			g2.setStroke(new BasicStroke(2));
			g.setColor(Color.BLACK);
			if (getModel().isRollover()) {
				Color highlight = new Color(0, 51, 153);
				g.setColor(highlight);
			}
			int delta = 5;
			g.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
			g.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
			g2.setStroke(stroke);

			int i = pane.indexOfTabComponent(ClosableTabComponent.this);
			pane.setTitleAt(i, label.getText());
		}
	}
}
