/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * 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.android.hierarchyviewer.ui;

import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.hierarchyviewer.device.DeviceBridge;
import com.android.hierarchyviewer.device.Window;
import com.android.hierarchyviewer.laf.UnifiedContentBorder;
import com.android.hierarchyviewer.scene.CaptureLoader;
import com.android.hierarchyviewer.scene.ProfilesLoader;
import com.android.hierarchyviewer.scene.VersionLoader;
import com.android.hierarchyviewer.scene.ViewHierarchyLoader;
import com.android.hierarchyviewer.scene.ViewHierarchyScene;
import com.android.hierarchyviewer.scene.ViewManager;
import com.android.hierarchyviewer.scene.ViewNode;
import com.android.hierarchyviewer.scene.WindowsLoader;
import com.android.hierarchyviewer.ui.action.CaptureLayersAction;
import com.android.hierarchyviewer.ui.action.CaptureNodeAction;
import com.android.hierarchyviewer.ui.action.DumpDisplayListAction;
import com.android.hierarchyviewer.ui.action.ExitAction;
import com.android.hierarchyviewer.ui.action.InvalidateAction;
import com.android.hierarchyviewer.ui.action.LoadGraphAction;
import com.android.hierarchyviewer.ui.action.RefreshWindowsAction;
import com.android.hierarchyviewer.ui.action.RequestLayoutAction;
import com.android.hierarchyviewer.ui.action.SaveSceneAction;
import com.android.hierarchyviewer.ui.action.ShowDevicesAction;
import com.android.hierarchyviewer.ui.action.StartServerAction;
import com.android.hierarchyviewer.ui.action.StopServerAction;
import com.android.hierarchyviewer.ui.model.ProfilesTableModel;
import com.android.hierarchyviewer.ui.model.PropertiesTableModel;
import com.android.hierarchyviewer.ui.model.ViewsTreeModel;
import com.android.hierarchyviewer.ui.util.IconLoader;
import com.android.hierarchyviewer.ui.util.PngFileFilter;
import com.android.hierarchyviewer.ui.util.PsdFileFilter;
import com.android.hierarchyviewer.util.OS;
import com.android.hierarchyviewer.util.WorkerThread;

import org.netbeans.api.visual.graph.layout.TreeGraphLayout;
import org.netbeans.api.visual.model.ObjectSceneEvent;
import org.netbeans.api.visual.model.ObjectSceneEventType;
import org.netbeans.api.visual.model.ObjectSceneListener;
import org.netbeans.api.visual.model.ObjectState;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.imageio.ImageIO;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;

public class Workspace extends JFrame {
    private JLabel viewCountLabel;
    private JSlider zoomSlider;
    private JSplitPane sideSplitter;
    private JSplitPane mainSplitter;
    private JTable propertiesTable;
    private JTable profilingTable;
    private JComponent pixelPerfectPanel;
    private JTree pixelPerfectTree;
    private ScreenViewer screenViewer;

    private JPanel extrasPanel;
    private LayoutRenderer layoutView;

    private JScrollPane sceneScroller;
    private JComponent sceneView;

    private ViewHierarchyScene scene;

    private ActionMap actionsMap;
    private JPanel mainPanel;
    private JProgressBar progress;
    private JToolBar buttonsPanel;
    private JToolBar commandButtonsPanel;

    private JComponent deviceSelector;
    private DevicesTableModel devicesTableModel;
    private WindowsTableModel windowsTableModel;

    private IDevice currentDevice;
    private Window currentWindow = Window.FOCUSED_WINDOW;

    private JButton displayNodeButton;
    private JButton dumpDisplayListButton;
    private JButton captureLayersButton;
    private JButton invalidateButton;
    private JButton requestLayoutButton;
    private JButton loadButton;
    private JButton startButton;
    private JButton stopButton;
    private JButton showDevicesButton;
    private JButton refreshButton;
    private JToggleButton graphViewButton;
    private JToggleButton pixelPerfectViewButton;
    private JMenuItem saveMenuItem;
    private JMenuItem showDevicesMenuItem;
    private JMenuItem loadMenuItem;
    private JMenuItem startMenuItem;
    private JMenuItem stopMenuItem;
    private JTable devices;
    private JTable windows;
    private JLabel minZoomLabel;
    private JLabel maxZoomLabel;
    private JTextField filterText;
    private JLabel filterLabel;

    private int protocolVersion;
    private int serverVersion;

    public Workspace() {
        super("Hierarchy Viewer");

        buildActions();
        add(buildMainPanel());
        setJMenuBar(buildMenuBar());

        devices.changeSelection(0, 0, false, false);
        currentDeviceChanged();

        pack();
    }

    private void buildActions() {
        actionsMap = new ActionMap();
        actionsMap.put(ExitAction.ACTION_NAME, new ExitAction(this));
        actionsMap.put(ShowDevicesAction.ACTION_NAME, new ShowDevicesAction(this));
        actionsMap.put(LoadGraphAction.ACTION_NAME, new LoadGraphAction(this));
        actionsMap.put(SaveSceneAction.ACTION_NAME, new SaveSceneAction(this));
        actionsMap.put(StartServerAction.ACTION_NAME, new StartServerAction(this));
        actionsMap.put(StopServerAction.ACTION_NAME, new StopServerAction(this));
        actionsMap.put(InvalidateAction.ACTION_NAME, new InvalidateAction(this));
        actionsMap.put(RequestLayoutAction.ACTION_NAME, new RequestLayoutAction(this));
        actionsMap.put(DumpDisplayListAction.ACTION_NAME, new DumpDisplayListAction(this));
        actionsMap.put(CaptureNodeAction.ACTION_NAME, new CaptureNodeAction(this));
        actionsMap.put(CaptureLayersAction.ACTION_NAME, new CaptureLayersAction(this));
        actionsMap.put(RefreshWindowsAction.ACTION_NAME, new RefreshWindowsAction(this));
    }

    private JComponent buildMainPanel() {
        mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());
        commandButtonsPanel = buildToolBar();
        mainPanel.add(commandButtonsPanel, BorderLayout.PAGE_START);
        mainPanel.add(deviceSelector = buildDeviceSelector(), BorderLayout.CENTER);
        mainPanel.add(buildStatusPanel(), BorderLayout.SOUTH);

        mainPanel.setPreferredSize(new Dimension(1200, 800));

        return mainPanel;
    }

    private JComponent buildGraphPanel() {
        sceneScroller = new JScrollPane();
        sceneScroller.setBorder(null);

        mainSplitter = new JSplitPane();
        mainSplitter.setResizeWeight(1.0);
        mainSplitter.setContinuousLayout(true);
        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
            mainSplitter.setBorder(new UnifiedContentBorder());
        }

        mainSplitter.setLeftComponent(sceneScroller);
        mainSplitter.setRightComponent(buildSideSplitter());

        return mainSplitter;
    }

    private JComponent buildDeviceSelector() {
        JPanel panel = new JPanel(new GridBagLayout());
        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
            panel.setBorder(new UnifiedContentBorder());
        }

        devicesTableModel = new DevicesTableModel();
        for (IDevice device : DeviceBridge.getDevices()) {
            DeviceBridge.setupDeviceForward(device);
            devicesTableModel.addDevice(device);
        }
        DeviceBridge.startListenForDevices(devicesTableModel);

        devices = new JTable(devicesTableModel);
        devices.getSelectionModel().addListSelectionListener(new DeviceSelectedListener());
        devices.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        devices.setBorder(null);
        JScrollPane devicesScroller = new JScrollPane(devices);
        devicesScroller.setBorder(null);
        panel.add(devicesScroller, new GridBagConstraints(0, 0, 1, 1, 0.5, 1.0,
                GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0),
                0, 0));

        windowsTableModel = new WindowsTableModel();
        windowsTableModel.setVisible(false);

        windows = new JTable(windowsTableModel);
        windows.getSelectionModel().addListSelectionListener(new WindowSelectedListener());
        windows.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        windows.setBorder(null);
        JScrollPane windowsScroller = new JScrollPane(windows);
        windowsScroller.setBorder(null);
        panel.add(windowsScroller, new GridBagConstraints(2, 0, 1, 1, 0.5, 1.0,
                GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0),
                0, 0));

        return panel;
    }

    private JComponent buildSideSplitter() {
        propertiesTable = new JTable();
        propertiesTable.setModel(new DefaultTableModel(new Object[][] { },
                new String[] { "Property", "Value" }));
        propertiesTable.setBorder(null);
        propertiesTable.getTableHeader().setBorder(null);

        JScrollPane tableScroller = new JScrollPane(propertiesTable);
        tableScroller.setBorder(null);

        profilingTable = new JTable();
        profilingTable.setModel(new DefaultTableModel(new Object[][] {
                { " " , " " }, { " " , " " }, { " " , " " } },
                new String[] { "Operation", "Duration (ms)" }));
        profilingTable.setBorder(null);
        profilingTable.getTableHeader().setBorder(null);

        JScrollPane firstTableScroller = new JScrollPane(profilingTable);
        firstTableScroller.setBorder(null);

        setVisibleRowCount(profilingTable, 5);
        firstTableScroller.setMinimumSize(profilingTable.getPreferredScrollableViewportSize());

        JSplitPane tablesSplitter = new JSplitPane();
        tablesSplitter.setBorder(null);
        tablesSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
        tablesSplitter.setResizeWeight(0);
        tablesSplitter.setLeftComponent(firstTableScroller);
        tablesSplitter.setBottomComponent(tableScroller);
        tablesSplitter.setContinuousLayout(true);

        sideSplitter = new JSplitPane();
        sideSplitter.setBorder(null);
        sideSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
        sideSplitter.setResizeWeight(0.5);
        sideSplitter.setLeftComponent(tablesSplitter);
        sideSplitter.setBottomComponent(null);
        sideSplitter.setContinuousLayout(true);

        return sideSplitter;
    }

    private JPanel buildStatusPanel() {
        JPanel statusPanel = new JPanel();
        statusPanel.setLayout(new BorderLayout());

        JPanel leftSide = new JPanel();
        leftSide.setOpaque(false);
        leftSide.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
        leftSide.add(Box.createHorizontalStrut(6));

        ButtonGroup group = new ButtonGroup();

        graphViewButton = new JToggleButton(IconLoader.load(getClass(),
                "/images/icon-graph-view.png"));
        graphViewButton.setSelectedIcon(IconLoader.load(getClass(),
                "/images/icon-graph-view-selected.png"));
        graphViewButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        graphViewButton.putClientProperty("JButton.segmentPosition", "first");
        graphViewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                toggleGraphView();
            }
        });
        group.add(graphViewButton);
        leftSide.add(graphViewButton);

        pixelPerfectViewButton = new JToggleButton(IconLoader.load(getClass(),
                "/images/icon-pixel-perfect-view.png"));
        pixelPerfectViewButton.setSelectedIcon(IconLoader.load(getClass(),
                "/images/icon-pixel-perfect-view-selected.png"));
        pixelPerfectViewButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        pixelPerfectViewButton.putClientProperty("JButton.segmentPosition", "last");
        pixelPerfectViewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                togglePixelPerfectView();
            }
        });
        group.add(pixelPerfectViewButton);
        leftSide.add(pixelPerfectViewButton);

        graphViewButton.setSelected(true);

        filterText = new JTextField(20);
        filterText.putClientProperty("JComponent.sizeVariant", "small");
        filterText.getDocument().addDocumentListener(new DocumentListener() {
            public void insertUpdate(DocumentEvent e) {
                updateFilter(e);
            }

            public void removeUpdate(DocumentEvent e) {
                updateFilter(e);
            }

            public void changedUpdate(DocumentEvent e) {
                updateFilter(e);
            }
        });

        filterLabel = new JLabel("Filter by class or id:");
        filterLabel.putClientProperty("JComponent.sizeVariant", "small");
        filterLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6));

        leftSide.add(filterLabel);
        leftSide.add(filterText);

        minZoomLabel = new JLabel();
        minZoomLabel.setText("20%");
        minZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
        minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
        leftSide.add(minZoomLabel);

        zoomSlider = new JSlider();
        zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
        zoomSlider.setMaximum(200);
        zoomSlider.setMinimum(20);
        zoomSlider.setValue(100);
        zoomSlider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                zoomSliderStateChanged(evt);
            }
        });
        leftSide.add(zoomSlider);

        maxZoomLabel = new JLabel();
        maxZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
        maxZoomLabel.setText("200%");
        leftSide.add(maxZoomLabel);

        viewCountLabel = new JLabel();
        viewCountLabel.setText("0 views");
        viewCountLabel.putClientProperty("JComponent.sizeVariant", "small");
        viewCountLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
        leftSide.add(viewCountLabel);

        statusPanel.add(leftSide, BorderLayout.LINE_START);

        JPanel rightSide = new JPanel();
        rightSide.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 12));
        rightSide.setLayout(new FlowLayout(FlowLayout.RIGHT));

        progress = new JProgressBar();
        progress.setVisible(false);
        progress.setIndeterminate(true);
        progress.putClientProperty("JComponent.sizeVariant", "mini");
        progress.putClientProperty("JProgressBar.style", "circular");
        rightSide.add(progress);

        statusPanel.add(rightSide, BorderLayout.LINE_END);

        hideStatusBarComponents();

        return statusPanel;
    }

    private void hideStatusBarComponents() {
        viewCountLabel.setVisible(false);
        zoomSlider.setVisible(false);
        minZoomLabel.setVisible(false);
        maxZoomLabel.setVisible(false);
        filterLabel.setVisible(false);
        filterText.setVisible(false);
    }

    private JToolBar buildToolBar() {
        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);
        toolBar.setRollover(true);

        startButton = new JButton();
        startButton.setAction(actionsMap.get(StartServerAction.ACTION_NAME));
        startButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        startButton.putClientProperty("JButton.segmentPosition", "first");
        toolBar.add(startButton);

        stopButton = new JButton();
        stopButton.setAction(actionsMap.get(StopServerAction.ACTION_NAME));
        stopButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        stopButton.putClientProperty("JButton.segmentPosition", "middle");
        toolBar.add(stopButton);

        refreshButton = new JButton();
        refreshButton.setAction(actionsMap.get(RefreshWindowsAction.ACTION_NAME));
        refreshButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        refreshButton.putClientProperty("JButton.segmentPosition", "last");
        toolBar.add(refreshButton);

        showDevicesButton = new JButton();
        showDevicesButton.setAction(actionsMap.get(ShowDevicesAction.ACTION_NAME));
        showDevicesButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        showDevicesButton.putClientProperty("JButton.segmentPosition", "first");
        toolBar.add(showDevicesButton);
        showDevicesButton.setEnabled(false);

        loadButton = new JButton();
        loadButton.setAction(actionsMap.get(LoadGraphAction.ACTION_NAME));
        loadButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        loadButton.putClientProperty("JButton.segmentPosition", "last");
        toolBar.add(loadButton);

        displayNodeButton = new JButton();
        displayNodeButton.setAction(actionsMap.get(CaptureNodeAction.ACTION_NAME));
        displayNodeButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        displayNodeButton.putClientProperty("JButton.segmentPosition", "first");
        toolBar.add(displayNodeButton);

        dumpDisplayListButton = new JButton();
        dumpDisplayListButton.setAction(actionsMap.get(DumpDisplayListAction.ACTION_NAME));
        dumpDisplayListButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        dumpDisplayListButton.putClientProperty("JButton.segmentPosition", "middle");

        captureLayersButton = new JButton();
        captureLayersButton.setAction(actionsMap.get(CaptureLayersAction.ACTION_NAME));
        captureLayersButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        captureLayersButton.putClientProperty("JButton.segmentPosition", "middle");
        toolBar.add(captureLayersButton);
        
        invalidateButton = new JButton();
        invalidateButton.setAction(actionsMap.get(InvalidateAction.ACTION_NAME));
        invalidateButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        invalidateButton.putClientProperty("JButton.segmentPosition", "middle");
        toolBar.add(invalidateButton);

        requestLayoutButton = new JButton();
        requestLayoutButton.setAction(actionsMap.get(RequestLayoutAction.ACTION_NAME));
        requestLayoutButton.putClientProperty("JButton.buttonType", "segmentedTextured");
        requestLayoutButton.putClientProperty("JButton.segmentPosition", "last");
        toolBar.add(requestLayoutButton);

        return toolBar;
    }

    private void setupProtocolDependentToolbar() {
        // Some functionality is only enabled in certain versions of the protocol.
        // Add/remove those buttons here
        if (protocolVersion < 4) {
            commandButtonsPanel.remove(dumpDisplayListButton);
        } else if (dumpDisplayListButton.getParent() == null) {
            commandButtonsPanel.add(dumpDisplayListButton,
                    commandButtonsPanel.getComponentCount() - 1);
        }
    }

    private JMenuBar buildMenuBar() {
        JMenuBar menuBar = new JMenuBar();

        JMenu fileMenu = new JMenu();
        JMenu viewMenu = new JMenu();
        JMenu viewHierarchyMenu = new JMenu();
        JMenu serverMenu = new JMenu();

        saveMenuItem = new JMenuItem();
        JMenuItem exitMenuItem = new JMenuItem();

        showDevicesMenuItem = new JMenuItem();

        loadMenuItem = new JMenuItem();

        startMenuItem = new JMenuItem();
        stopMenuItem = new JMenuItem();

        fileMenu.setText("File");

        saveMenuItem.setAction(actionsMap.get(SaveSceneAction.ACTION_NAME));
        fileMenu.add(saveMenuItem);

        exitMenuItem.setAction(actionsMap.get(ExitAction.ACTION_NAME));
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        viewMenu.setText("View");

        showDevicesMenuItem.setAction(actionsMap.get(ShowDevicesAction.ACTION_NAME));
        showDevicesMenuItem.setEnabled(false);
        viewMenu.add(showDevicesMenuItem);

        menuBar.add(viewMenu);

        viewHierarchyMenu.setText("Hierarchy");

        loadMenuItem.setAction(actionsMap.get(LoadGraphAction.ACTION_NAME));
        viewHierarchyMenu.add(loadMenuItem);

        menuBar.add(viewHierarchyMenu);

        serverMenu.setText("Server");

        startMenuItem.setAction(actionsMap.get(StartServerAction.ACTION_NAME));
        serverMenu.add(startMenuItem);

        stopMenuItem.setAction(actionsMap.get(StopServerAction.ACTION_NAME));
        serverMenu.add(stopMenuItem);

        menuBar.add(serverMenu);

        return menuBar;
    }

    private JComponent buildPixelPerfectPanel() {
        JSplitPane splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);

        pixelPerfectTree = new JTree(new Object[0]);
        pixelPerfectTree.setBorder(null);
        pixelPerfectTree.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
        pixelPerfectTree.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent event) {
                ViewNode node = (ViewNode) event.getPath().getLastPathComponent();
                screenViewer.select(node);
            }
        });

        JScrollPane scroller = new JScrollPane(pixelPerfectTree);
        scroller.setBorder(null);
        scroller.getViewport().setBorder(null);

        splitter.setContinuousLayout(true);
        splitter.setLeftComponent(scroller);
        splitter.setRightComponent(buildPixelPerfectViewer(splitter));
        splitter.setBorder(null);

        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
            splitter.setBorder(new UnifiedContentBorder());
        }

        return splitter;
    }

    private JComponent buildPixelPerfectViewer(JSplitPane splitter) {
        screenViewer = new ScreenViewer(this, currentDevice, splitter.getDividerSize());
        return screenViewer;
    }

    private void toggleGraphView() {
        showStatusBarComponents();

        screenViewer.stop();
        mainPanel.remove(pixelPerfectPanel);
        mainPanel.add(mainSplitter, BorderLayout.CENTER);

        validate();
        repaint();
    }

    private void showStatusBarComponents() {
        viewCountLabel.setVisible(true);
        zoomSlider.setVisible(true);
        minZoomLabel.setVisible(true);
        maxZoomLabel.setVisible(true);
        filterLabel.setVisible(true);
        filterText.setVisible(true);
    }

    private void togglePixelPerfectView() {
        if (pixelPerfectPanel == null) {
            pixelPerfectPanel = buildPixelPerfectPanel();
            showPixelPerfectTree();
        } else {
            screenViewer.start();
        }

        hideStatusBarComponents();

        mainPanel.remove(mainSplitter);
        mainPanel.add(pixelPerfectPanel, BorderLayout.CENTER);

        validate();
        repaint();
    }

    private void zoomSliderStateChanged(ChangeEvent evt) {
        JSlider slider = (JSlider) evt.getSource();
        if (sceneView != null) {
            scene.setZoomFactor(slider.getValue() / 100.0d);
            sceneView.repaint();
        }
    }

    private void showProperties(ViewNode node) {
        propertiesTable.setModel(new PropertiesTableModel(node));
    }

    private void updateProfiles(double[] profiles) {
        profilingTable.setModel(new ProfilesTableModel(profiles));
        setVisibleRowCount(profilingTable, profiles.length + 1);
    }

    public static void setVisibleRowCount(JTable table, int rows) {
        int height = 0;
        for (int row = 0; row < rows; row++) {
            height += table.getRowHeight(row);
        }

        Dimension size = new Dimension(table.getPreferredScrollableViewportSize().width, height);
        table.setPreferredScrollableViewportSize(size);
        table.revalidate();
    }

    private void showPixelPerfectTree() {
        if (pixelPerfectTree == null) {
            return;
        }
        pixelPerfectTree.setModel(new ViewsTreeModel(scene.getRoot()));
        pixelPerfectTree.setCellRenderer(new ViewsTreeCellRenderer());
        expandAll(pixelPerfectTree, true);

    }

    private static void expandAll(JTree tree, boolean expand) {
        ViewNode root = (ViewNode) tree.getModel().getRoot();
        expandAll(tree, new TreePath(root), expand);
    }

    private static void expandAll(JTree tree, TreePath parent, boolean expand) {
        // Traverse children
        ViewNode node = (ViewNode)parent.getLastPathComponent();
        if (node.children != null) {
            for (ViewNode n : node.children) {
                TreePath path = parent.pathByAddingChild(n);
                expandAll(tree, path, expand);
            }
        }

        if (expand) {
            tree.expandPath(parent);
        } else {
            tree.collapsePath(parent);
        }
    }

    private void createGraph(ViewHierarchyScene scene) {
        scene.addObjectSceneListener(new SceneFocusListener(),
                ObjectSceneEventType.OBJECT_FOCUS_CHANGED);

        if (mainSplitter == null) {
            mainPanel.remove(deviceSelector);
            mainPanel.add(buildGraphPanel(), BorderLayout.CENTER);
            showDevicesButton.setEnabled(true);
            showDevicesMenuItem.setEnabled(true);
            graphViewButton.setEnabled(true);
            pixelPerfectViewButton.setEnabled(true);

            showStatusBarComponents();
        }

        sceneView = scene.createView();
        sceneView.addMouseListener(new NodeClickListener());
        sceneView.addMouseWheelListener(new WheelZoomListener());
        sceneScroller.setViewportView(sceneView);

        if (extrasPanel != null) {
            sideSplitter.remove(extrasPanel);
        }
        sideSplitter.setBottomComponent(buildExtrasPanel());

        mainSplitter.setDividerLocation(getWidth() - mainSplitter.getDividerSize() -
                buttonsPanel.getPreferredSize().width);

        captureLayersButton.setEnabled(true);        
        saveMenuItem.setEnabled(true);
        showPixelPerfectTree();

        updateStatus();
        layoutScene();
    }

    private void layoutScene() {
        TreeGraphLayout<ViewNode, String> layout =
                new TreeGraphLayout<ViewNode, String>(scene, 50, 50, 70, 30, true);
        layout.layout(scene.getRoot());
    }

    private void updateStatus() {
        viewCountLabel.setText("" + scene.getNodes().size() + " views");
        zoomSlider.setEnabled(scene.getNodes().size() > 0);
    }

    private JPanel buildExtrasPanel() {
        extrasPanel = new JPanel(new BorderLayout());
        JScrollPane p = new JScrollPane(layoutView = new LayoutRenderer(scene, sceneView));
        JScrollBar b = p.getVerticalScrollBar();
        b.setUnitIncrement(10);
        extrasPanel.add(p);
        extrasPanel.add(scene.createSatelliteView(), BorderLayout.SOUTH);
        extrasPanel.add(buildLayoutViewControlButtons(), BorderLayout.NORTH);
        return extrasPanel;
    }

    private JComponent buildLayoutViewControlButtons() {
        buttonsPanel = new JToolBar();
        buttonsPanel.setFloatable(false);

        ButtonGroup group = new ButtonGroup();

        JToggleButton white = new JToggleButton("On White");
        toggleColorOnSelect(white);
        white.putClientProperty("JButton.buttonType", "segmentedTextured");
        white.putClientProperty("JButton.segmentPosition", "first");
        white.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                layoutView.setBackground(Color.WHITE);
                layoutView.setForeground(Color.BLACK);
            }
        });
        group.add(white);
        buttonsPanel.add(white);

        JToggleButton black = new JToggleButton("On Black");
        toggleColorOnSelect(black);
        black.putClientProperty("JButton.buttonType", "segmentedTextured");
        black.putClientProperty("JButton.segmentPosition", "last");
        black.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                layoutView.setBackground(Color.BLACK);
                layoutView.setForeground(Color.WHITE);
            }
        });
        group.add(black);
        buttonsPanel.add(black);

        black.setSelected(true);

        JCheckBox showExtras = new JCheckBox("Show Extras");
        showExtras.putClientProperty("JComponent.sizeVariant", "small");
        showExtras.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                layoutView.setShowExtras(((JCheckBox) e.getSource()).isSelected());
            }
        });
        buttonsPanel.add(showExtras);

        return buttonsPanel;
    }

    private void showCaptureWindow(ViewNode node, String captureParams, Image image) {
        if (image != null) {
            layoutView.repaint();

            JFrame frame = new JFrame(captureParams);
            JPanel panel = new JPanel(new BorderLayout());

            final CaptureRenderer label = new CaptureRenderer(new ImageIcon(image), node);
            label.setBorder(BorderFactory.createEmptyBorder(24, 24, 24, 24));

            final JPanel solidColor = new JPanel(new BorderLayout());
            solidColor.setBackground(Color.BLACK);
            solidColor.add(label);

            JToolBar toolBar = new JToolBar();
            toolBar.setFloatable(false);

            ButtonGroup group = new ButtonGroup();

            JToggleButton white = new JToggleButton("On White");
            toggleColorOnSelect(white);
            white.putClientProperty("JButton.buttonType", "segmentedTextured");
            white.putClientProperty("JButton.segmentPosition", "first");
            white.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    solidColor.setBackground(Color.WHITE);
                }
            });
            group.add(white);
            toolBar.add(white);

            JToggleButton black = new JToggleButton("On Black");
            toggleColorOnSelect(black);
            black.putClientProperty("JButton.buttonType", "segmentedTextured");
            black.putClientProperty("JButton.segmentPosition", "last");
            black.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    solidColor.setBackground(Color.BLACK);
                }
            });
            group.add(black);
            toolBar.add(black);

            black.setSelected(true);

            JCheckBox showExtras = new JCheckBox("Show Extras");
            showExtras.addChangeListener(new ChangeListener() {
                public void stateChanged(ChangeEvent e) {
                    label.setShowExtras(((JCheckBox) e.getSource()).isSelected());
                }
            });
            toolBar.add(showExtras);

            panel.add(toolBar, BorderLayout.NORTH);
            panel.add(solidColor);
            frame.add(panel);

            frame.pack();
            frame.setResizable(false);
            frame.setLocationRelativeTo(Workspace.this);
            frame.setVisible(true);
        }
    }

    private void reset() {
        currentDevice = null;
        currentWindow = null;
        currentDeviceChanged();
        windowsTableModel.setVisible(false);
        windowsTableModel.clear();

        showDevicesSelector();
    }

    public void showDevicesSelector() {
        if (mainSplitter != null) {
            if (pixelPerfectPanel != null) {
                screenViewer.start();
            }
            mainPanel.remove(graphViewButton.isSelected() ? mainSplitter : pixelPerfectPanel);
            mainPanel.add(deviceSelector, BorderLayout.CENTER);
            pixelPerfectPanel = mainSplitter = null;
            graphViewButton.setSelected(true);

            hideStatusBarComponents();

            saveMenuItem.setEnabled(false);
            showDevicesMenuItem.setEnabled(false);
            showDevicesButton.setEnabled(false);
            displayNodeButton.setEnabled(false);
            captureLayersButton.setEnabled(false);
            invalidateButton.setEnabled(false);
            dumpDisplayListButton.setEnabled(false);
            requestLayoutButton.setEnabled(false);
            graphViewButton.setEnabled(false);
            pixelPerfectViewButton.setEnabled(false);

            if (currentDevice != null) {
                if (!DeviceBridge.isViewServerRunning(currentDevice)) {
                    DeviceBridge.startViewServer(currentDevice);
                }
                loadWindows().execute();
                windowsTableModel.setVisible(true);
            }

            validate();
            repaint();
        }
    }

    private void currentDeviceChanged() {
        if (currentDevice == null) {
            startButton.setEnabled(false);
            startMenuItem.setEnabled(false);
            stopButton.setEnabled(false);
            stopMenuItem.setEnabled(false);
            refreshButton.setEnabled(false);
            saveMenuItem.setEnabled(false);
            loadButton.setEnabled(false);
            displayNodeButton.setEnabled(false);
            captureLayersButton.setEnabled(false);
            invalidateButton.setEnabled(false);
            dumpDisplayListButton.setEnabled(false);
            graphViewButton.setEnabled(false);
            pixelPerfectViewButton.setEnabled(false);
            requestLayoutButton.setEnabled(false);
            loadMenuItem.setEnabled(false);
        } else {
            loadMenuItem.setEnabled(true);
            checkForServerOnCurrentDevice();
        }
    }

    private void checkForServerOnCurrentDevice() {
        if (DeviceBridge.isViewServerRunning(currentDevice)) {
            startButton.setEnabled(false);
            startMenuItem.setEnabled(false);
            stopButton.setEnabled(true);
            stopMenuItem.setEnabled(true);
            loadButton.setEnabled(true);
            refreshButton.setEnabled(true);
        } else {
            startButton.setEnabled(true);
            startMenuItem.setEnabled(true);
            stopButton.setEnabled(false);
            stopMenuItem.setEnabled(false);
            loadButton.setEnabled(false);
            refreshButton.setEnabled(false);
        }
    }

    public void cleanupDevices() {
        for (IDevice device : devicesTableModel.getDevices()) {
            DeviceBridge.removeDeviceForward(device);
        }
    }

    private static void toggleColorOnSelect(JToggleButton button) {
        if (!OS.isMacOsX() || !OS.isLeopardOrLater()) {
            return;
        }

        button.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent event) {
                JToggleButton button = (JToggleButton) event.getSource();
                if (button.isSelected()) {
                    button.setForeground(Color.WHITE);
                } else {
                    button.setForeground(Color.BLACK);
                }
            }
        });
    }

    private void updateFilter(DocumentEvent e) {
        final Document document = e.getDocument();
        try {
            updateFilteredNodes(document.getText(0, document.getLength()));
        } catch (BadLocationException e1) {
            e1.printStackTrace();
        }
    }

    private void updateFilteredNodes(String filterText) {
        final ViewNode root = scene.getRoot();
        try {
            final Pattern pattern = Pattern.compile(filterText, Pattern.CASE_INSENSITIVE);
            filterNodes(pattern, root);
        } catch (PatternSyntaxException e) {
            filterNodes(null, root);
        }
        repaint();
    }

    private void filterNodes(Pattern pattern, ViewNode root) {
        root.filter(pattern);

        for (ViewNode node : root.children) {
            filterNodes(pattern, node);
        }
    }

    public void beginTask() {
        progress.setVisible(true);
    }

    public void endTask() {
        progress.setVisible(false);
    }

    public SwingWorker<?, ?> showNodeCapture() {
        if (scene.getFocusedObject() == null) {
            return null;
        }
        return new CaptureNodeTask();
    }
    
    public SwingWorker<?, ?> outputDisplayList() {
        if (scene.getFocusedObject() == null) {
            return null;
        }
        return new DumpDisplayListTask();
    }

    public SwingWorker<?, ?> captureLayers() {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileFilter(new PsdFileFilter());
        int choice = chooser.showSaveDialog(sceneView);
        if (choice == JFileChooser.APPROVE_OPTION) {
            return new CaptureLayersTask(chooser.getSelectedFile());
        } else {
            return null;
        }        
    }

    public SwingWorker<?, ?> startServer() {
        return new StartServerTask();
    }

    public SwingWorker<?, ?> stopServer() {
        return new StopServerTask();
    }

    public SwingWorker<?, ?> loadWindows() {
        return new LoadWindowsTask();
    }

    public SwingWorker<?, ?> loadGraph() {
        return new LoadGraphTask();
    }

    public SwingWorker<?, ?> invalidateView() {
        if (scene.getFocusedObject() == null) {
            return null;
        }
        return new InvalidateTask();
    }

    public SwingWorker<?, ?> requestLayout() {
        if (scene.getFocusedObject() == null) {
            return null;
        }
        return new RequestLayoutTask();
    }

    public SwingWorker<?, ?> saveSceneAsImage() {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileFilter(new PngFileFilter());
        int choice = chooser.showSaveDialog(sceneView);
        if (choice == JFileChooser.APPROVE_OPTION) {
            return new SaveSceneTask(chooser.getSelectedFile());
        } else {
            return null;
        }
    }

    private class InvalidateTask extends SwingWorker<Object, Void> {
        private String captureParams;

        private InvalidateTask() {
            captureParams = scene.getFocusedObject().toString();
            beginTask();
        }

        @Override
        @WorkerThread
        protected Object doInBackground() throws Exception {
            ViewManager.invalidate(currentDevice, currentWindow, captureParams);
            return null;
        }

        @Override
        protected void done() {
            endTask();
        }
    }

    private class DumpDisplayListTask extends SwingWorker<Object, Void> {
        private String captureParams;

        private DumpDisplayListTask() {
            captureParams = scene.getFocusedObject().toString();
            beginTask();
        }

        @Override
        @WorkerThread
        protected Object doInBackground() throws Exception {
            ViewManager.outputDisplayList(currentDevice, currentWindow, captureParams);
            return null;
        }

        @Override
        protected void done() {
            endTask();
        }
    }

    private class RequestLayoutTask extends SwingWorker<Object, Void> {
        private String captureParams;

        private RequestLayoutTask() {
            captureParams = scene.getFocusedObject().toString();
            beginTask();
        }

        @Override
        @WorkerThread
        protected Object doInBackground() throws Exception {
            ViewManager.requestLayout(currentDevice, currentWindow, captureParams);
            return null;
        }

        @Override
        protected void done() {
            endTask();
        }
    }
    
    private class CaptureLayersTask extends SwingWorker<Boolean, Void> {
        private File file;

        private CaptureLayersTask(File file) {
            this.file = file;
            beginTask();
        }

        @Override
        @WorkerThread
        protected Boolean doInBackground() throws Exception {
            return CaptureLoader.saveLayers(currentDevice, currentWindow, file);
        }

        @Override
        protected void done() {
            endTask();
        }
    }

    private class CaptureNodeTask extends SwingWorker<Image, Void> {
        private String captureParams;
        private ViewNode node;

        private CaptureNodeTask() {
            node = (ViewNode) scene.getFocusedObject();
            captureParams = node.toString();
            beginTask();
        }

        @Override
        @WorkerThread
        protected Image doInBackground() throws Exception {
            node.image = CaptureLoader.loadCapture(currentDevice, currentWindow, captureParams);
            return node.image;
        }

        @Override
        protected void done() {
            try {
                Image image = get();
                showCaptureWindow(node, captureParams, image);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                endTask();
            }
        }
    }
    
    static class WindowsResult {
        Window[] windows;
        int serverVersion;
        int protocolVersion;
    }

    private class LoadWindowsTask extends SwingWorker<WindowsResult, Void> {
        private LoadWindowsTask() {
            beginTask();
        }

        @Override
        @WorkerThread
        protected WindowsResult doInBackground() throws Exception {
            WindowsResult r = new WindowsResult();
            r.protocolVersion = VersionLoader.loadProtocolVersion(currentDevice);
            r.serverVersion = VersionLoader.loadServerVersion(currentDevice);
            r.windows = WindowsLoader.loadWindows(currentDevice,
                    r.protocolVersion, r.serverVersion);
            return r;
        }

        @Override
        protected void done() {
            try {
                WindowsResult result = get();
                protocolVersion = result.protocolVersion;
                serverVersion = result.serverVersion;
                setupProtocolDependentToolbar();
                windowsTableModel.clear();
                windowsTableModel.addWindows(result.windows);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                endTask();
            }
        }
    }

    private class StartServerTask extends SwingWorker<Object, Void> {
        public StartServerTask() {
            beginTask();
        }

        @Override
        @WorkerThread
        protected Object doInBackground() {
            DeviceBridge.startViewServer(currentDevice);
            return null;
        }

        @Override
        protected void done() {
            new LoadWindowsTask().execute();
            windowsTableModel.setVisible(true);
            checkForServerOnCurrentDevice();
            endTask();
        }
    }

    private class StopServerTask extends SwingWorker<Object, Void> {
        public StopServerTask() {
            beginTask();
        }

        @Override
        @WorkerThread
        protected Object doInBackground() {
            DeviceBridge.stopViewServer(currentDevice);
            return null;
        }

        @Override
        protected void done() {
            windowsTableModel.setVisible(false);
            windowsTableModel.clear();
            checkForServerOnCurrentDevice();
            endTask();
        }
    }

    private class LoadGraphTask extends SwingWorker<double[], Void> {
        public LoadGraphTask() {
            beginTask();
        }

        @Override
        @WorkerThread
        protected double[] doInBackground() {
            scene = ViewHierarchyLoader.loadScene(currentDevice, currentWindow);
            return ProfilesLoader.loadProfiles(currentDevice, currentWindow,
                    scene.getRoot().toString());
        }

        @Override
        protected void done() {
            try {
                createGraph(scene);
                updateProfiles(get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                endTask();
            }
        }
    }

    private class SaveSceneTask extends SwingWorker<Object, Void> {
        private File file;

        private SaveSceneTask(File file) {
            this.file = file;
            beginTask();
        }

        @Override
        @WorkerThread
        protected Object doInBackground() {
            if (sceneView == null) {
                return null;
            }

            try {
                BufferedImage image = new BufferedImage(sceneView.getWidth(),
                        sceneView.getHeight(), BufferedImage.TYPE_INT_RGB);
                Graphics2D g2 = image.createGraphics();
                sceneView.paint(g2);
                g2.dispose();
                ImageIO.write(image, "PNG", file);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return null;
        }

        @Override
        protected void done() {
            endTask();
        }
    }

    private class SceneFocusListener implements ObjectSceneListener {

        public void objectAdded(ObjectSceneEvent arg0, Object arg1) {
        }

        public void objectRemoved(ObjectSceneEvent arg0, Object arg1) {
        }

        public void objectStateChanged(ObjectSceneEvent arg0, Object arg1,
                ObjectState arg2, ObjectState arg3) {
        }

        public void selectionChanged(ObjectSceneEvent e, Set<Object> previousSelection,
                Set<Object> newSelection) {
        }

        public void highlightingChanged(ObjectSceneEvent arg0, Set<Object> arg1, Set<Object> arg2) {
        }

        public void hoverChanged(ObjectSceneEvent arg0, Object arg1, Object arg2) {
        }

        public void focusChanged(ObjectSceneEvent e, Object oldFocus, Object newFocus) {
            displayNodeButton.setEnabled(true);
            invalidateButton.setEnabled(true);
            dumpDisplayListButton.setEnabled(true);
            requestLayoutButton.setEnabled(true);

            Set<Object> selection = new HashSet<Object>();
            selection.add(newFocus);
            scene.setSelectedObjects(selection);

            showProperties((ViewNode) newFocus);
            layoutView.repaint();
        }
    }

    private class NodeClickListener extends MouseAdapter {
        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
                showNodeCapture().execute();
            }
        }
    }

    private class WheelZoomListener implements MouseWheelListener {
        public void mouseWheelMoved(MouseWheelEvent e) {
            if (zoomSlider != null) {
                int val = zoomSlider.getValue();
                val -= e.getWheelRotation() * 10;
                zoomSlider.setValue(val);
            }
        }
    }
    private class DevicesTableModel extends DefaultTableModel implements
            AndroidDebugBridge.IDeviceChangeListener {

        private ArrayList<IDevice> devices;

        private DevicesTableModel() {
            devices = new ArrayList<IDevice>();
        }

        @Override
        public int getColumnCount() {
            return 1;
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }

        @Override
        public Object getValueAt(int row, int column) {
            return devices.get(row);
        }

        @Override
        public String getColumnName(int column) {
            return "Devices";
        }

        @WorkerThread
        public void deviceConnected(final IDevice device) {
            DeviceBridge.setupDeviceForward(device);

            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    addDevice(device);
                }
            });
        }

        @WorkerThread
        public void deviceDisconnected(final IDevice device) {
            DeviceBridge.removeDeviceForward(device);

            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    removeDevice(device);
                }
            });
        }

        public void addDevice(IDevice device) {
            if (!devices.contains(device)) {
                devices.add(device);
                fireTableDataChanged();
            }
        }

        public void removeDevice(IDevice device) {
            if (device.equals(currentDevice)) {
                reset();
            }

            if (devices.contains(device)) {
                devices.remove(device);
                fireTableDataChanged();
            }
        }

        @WorkerThread
        public void deviceChanged(IDevice device, int changeMask) {
            if ((changeMask & IDevice.CHANGE_STATE) != 0 &&
                    device.isOnline()) {
                // if the device state changed and it's now online, we set up its port forwarding.
                DeviceBridge.setupDeviceForward(device);
            } else if (device == currentDevice && (changeMask & IDevice.CHANGE_CLIENT_LIST) != 0) {
                // if the changed device is the current one and the client list changed, we update
                // the UI.
                loadWindows().execute();
                windowsTableModel.setVisible(true);
            }
        }

        @Override
        public int getRowCount() {
            return devices == null ? 0 : devices.size();
        }

        public IDevice getDevice(int index) {
            return index < devices.size() ? devices.get(index) : null;
        }

        public IDevice[] getDevices() {
            return devices.toArray(new IDevice[devices.size()]);
        }
    }

    private static class WindowsTableModel extends DefaultTableModel {
        private ArrayList<Window> windows;
        private boolean visible;

        private WindowsTableModel() {
            windows = new ArrayList<Window>();
            windows.add(Window.FOCUSED_WINDOW);
        }

        @Override
        public int getColumnCount() {
            return 1;
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }

        @Override
        public String getColumnName(int column) {
            return "Windows";
        }

        @Override
        public Object getValueAt(int row, int column) {
            return windows.get(row);
        }

        @Override
        public int getRowCount() {
            return !visible || windows == null ? 0 : windows.size();
        }

        public void setVisible(boolean visible) {
            this.visible = visible;
            fireTableDataChanged();
        }

        public void addWindow(Window window) {
            windows.add(window);
            fireTableDataChanged();
        }

        public void addWindows(Window[] windowsList) {
            //noinspection ManualArrayToCollectionCopy
            for (Window window : windowsList) {
                windows.add(window);
            }
            fireTableDataChanged();
        }

        public void clear() {
            windows.clear();
            windows.add(Window.FOCUSED_WINDOW);
        }

        public Window getWindow(int index) {
            return windows.get(index);
        }
    }

    private class DeviceSelectedListener implements ListSelectionListener {
        public void valueChanged(ListSelectionEvent event) {
            if (event.getValueIsAdjusting()) {
                return;
            }

            int row = devices.getSelectedRow();
            if (row >= 0) {
                currentDevice = devicesTableModel.getDevice(row);
                currentDeviceChanged();
                if (currentDevice != null) {
                    if (!DeviceBridge.isViewServerRunning(currentDevice)) {
                        DeviceBridge.startViewServer(currentDevice);
                        checkForServerOnCurrentDevice();
                    }
                    loadWindows().execute();
                    windowsTableModel.setVisible(true);
                }
            } else {
                currentDevice = null;
                currentDeviceChanged();
                windowsTableModel.setVisible(false);
                windowsTableModel.clear();
            }
        }
    }

    private class WindowSelectedListener implements ListSelectionListener {
        public void valueChanged(ListSelectionEvent event) {
            if (event.getValueIsAdjusting()) {
                return;
            }

            int row = windows.getSelectedRow();
            if (row >= 0) {
                currentWindow = windowsTableModel.getWindow(row);
            } else {
                currentWindow = Window.FOCUSED_WINDOW;
            }
        }
    }

    private static class ViewsTreeCellRenderer extends DefaultTreeCellRenderer {
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
                boolean expanded, boolean leaf, int row, boolean hasFocus) {

            final String name = ((ViewNode) value).name;
            value = name.substring(name.lastIndexOf('.') + 1, name.lastIndexOf('@'));
            return super.getTreeCellRendererComponent(tree, value, selected, expanded,
                    leaf, row, hasFocus);
        }
    }
}
