/*
 * Copyright 1999-2011 Alibaba Group Holding Ltd.
 *
 * 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.alibaba.druid.support.jconsole.model;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;

import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;

/**
 * 用于显示RowHeader的JTable，只需要将其加入JScrollPane的RowHeaderView即可为JTable生成行标题
 */
public class RowHeaderTable extends JTable {

    private static final long serialVersionUID = 1L;

    /**
     * 为JTable添加RowHeader，
     * 
     * @param refTable 需要添加rowHeader的JTable
     * @param columnWideth rowHeader的宽度
     */
    public RowHeaderTable(JTable refTable, int columnWidth){
        this(null, refTable, columnWidth, 1);
    }

    public RowHeaderTable(ArrayList<String> title, JTable refTable, int columnWidth){
        this(title, refTable, columnWidth, 1);
    }

    public RowHeaderTable(ArrayList<String> title, JTable refTable, int columnWidth, int rowSpan){
        super(new DefaultTableModel(refTable.getRowCount() / rowSpan, 1));
        this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);// 不可以调整列宽
        this.getColumnModel().getColumn(0).setPreferredWidth(columnWidth);
        this.setDefaultRenderer(Object.class, new RowHeaderRenderer(title, refTable, this, rowSpan));// 设置渲染器
        this.setPreferredScrollableViewportSize(new Dimension(columnWidth, 0));
    }
}

/**
 * 用于显示RowHeader的JTable的渲染器，当选择某行时，该行颜色会发生变化
 */
final class RowHeaderRenderer extends JLabel implements TableCellRenderer, ListSelectionListener {

    private static final long serialVersionUID = 1L;
    private JTable            reftable;              // 需要添加rowHeader的JTable
    private JTable            tableShow;             // 用于显示rowHeader的JTable
    private ArrayList<String> headerList;
    private int               rowHeightNow;
    private int               rowSpan;

    public RowHeaderRenderer(JTable reftable, JTable tableShow){
        this(null, reftable, tableShow, 0);
    }

    public RowHeaderRenderer(ArrayList<String> headerList, JTable reftable, JTable tableShow, int rowSpan){
        this.headerList = headerList;
        this.reftable = reftable;
        this.tableShow = tableShow;
        // 增加监听器，实现当在reftable中选择行时，RowHeader会发生颜色变化
        ListSelectionModel listModel = reftable.getSelectionModel();
        listModel.addListSelectionListener(this);
        rowHeightNow = reftable.getRowCount() * reftable.getRowHeight();
        this.rowSpan = rowSpan;
        if (rowSpan > 1) {
            rowHeightNow = rowSpan * reftable.getRowHeight();
        }
    }

    public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus,
                                                   int row, int col) {
        int rowCountNow = reftable.getRowCount() / rowSpan;
        ((DefaultTableModel) table.getModel()).setRowCount(rowCountNow);
        JTableHeader header = reftable.getTableHeader();
        this.setOpaque(true);
        setBorder(UIManager.getBorder("TableHeader.cellBorder"));// 设置为TableHeader的边框类型
        setHorizontalAlignment(CENTER);// 让text居中显示
        setBackground(header.getBackground());// 设置背景色为TableHeader的背景色
        if (isSelect(row)) // 当选取单元格时,在row header上设置成选取颜色
        {
            setForeground(Color.white);
            setBackground(Color.lightGray);
        } else {
            setForeground(header.getForeground());
        }
        setFont(header.getFont());
        if (row <= rowCountNow) {
            showCol(row);
        }
        return this;
    }

    private void showCol(int row) {

        String text = null;
        if (headerList != null && row < headerList.size()) {
            text = headerList.get(row);
        } else {
            text = String.valueOf(row + 1);
        }
        if (rowSpan > 1) {
            setText(text);
            this.tableShow.setRowHeight(row, rowHeightNow);
        } else {
            setText(text);
        }

    }

    public void valueChanged(ListSelectionEvent e) {
        this.tableShow.repaint();
    }

    private boolean isSelect(int row) {
        int[] sel = reftable.getSelectedRows();
        if (rowSpan <= 1) {
            for (int i = 0, len = sel.length; i < len; i++) {
                if (sel[i] == row) {
                    return true;
                }
            }
        } else {
            for (int i = 0, len = sel.length; i < len; i++) {
                if (sel[i] / rowSpan == row) {
                    return true;
                }
            }
        }

        return false;
    }
}
