1package autotest.common.ui;
2
3import autotest.common.CustomHistory;
4import autotest.common.CustomHistory.CustomHistoryListener;
5
6import com.google.gwt.event.dom.client.ClickEvent;
7import com.google.gwt.event.dom.client.ClickHandler;
8import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
9import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
10import com.google.gwt.event.logical.shared.SelectionEvent;
11import com.google.gwt.event.logical.shared.SelectionHandler;
12import com.google.gwt.event.logical.shared.ValueChangeEvent;
13import com.google.gwt.event.logical.shared.ValueChangeHandler;
14import com.google.gwt.user.client.Timer;
15import com.google.gwt.user.client.ui.Button;
16import com.google.gwt.user.client.ui.CheckBox;
17import com.google.gwt.user.client.ui.Composite;
18import com.google.gwt.user.client.ui.DeckPanel;
19import com.google.gwt.user.client.ui.HorizontalPanel;
20import com.google.gwt.user.client.ui.Panel;
21import com.google.gwt.user.client.ui.TabPanel;
22import com.google.gwt.user.client.ui.VerticalPanel;
23
24import java.util.ArrayList;
25import java.util.Collections;
26import java.util.List;
27import java.util.Map;
28
29public class CustomTabPanel extends Composite implements CustomHistoryListener,
30                                                         BeforeSelectionHandler<Integer>,
31                                                         SelectionHandler<Integer> {
32    private static final int AUTOREFRESH_INTERVAL = 5000; // millisecond
33
34    protected TabPanel tabPanel = new TabPanel();
35    protected Panel otherWidgetsPanel = new HorizontalPanel();
36    private Panel commonAreaPanel = new VerticalPanel();
37    protected Button refreshButton = new Button("Refresh");
38    protected CheckBox autorefreshCheckbox = new CheckBox("Auto Refresh");
39    protected int topBarHeight = 0;
40    protected List<TabView> tabViews = new ArrayList<TabView>();
41    private boolean doUpdateHistory = true;
42    private Timer autorefreshTimer;
43
44    public CustomTabPanel() {
45        VerticalPanel container = new VerticalPanel();
46        HorizontalPanel top = new HorizontalPanel();
47        VerticalPanel bottom = new VerticalPanel();
48        container.add(top);
49        container.add(bottom);
50
51        // put the TabBar at the top left
52        top.add(tabPanel.getTabBar());
53        top.setCellHeight(tabPanel.getTabBar(), "100%");
54        tabPanel.getTabBar().setHeight("100%");
55
56        // make a place for other widgets next to the tab bar
57        top.add(otherWidgetsPanel);
58
59        // put a common area above the tab deck
60        commonAreaPanel.setWidth("100%");
61        bottom.add(commonAreaPanel);
62
63        // put the TabPanel's DeckPanel below
64        DeckPanel tabDeck = tabPanel.getDeckPanel();
65        bottom.add(tabDeck);
66        bottom.setCellHeight(tabDeck, "100%");
67
68        tabPanel.addBeforeSelectionHandler(this);
69        tabPanel.addSelectionHandler(this);
70
71        // transfer the DeckPanel's class to the entire bottom panel
72        String tabDeckClass = tabDeck.getStyleName();
73        tabDeck.setStyleName("");
74        bottom.setStyleName(tabDeckClass);
75        bottom.setWidth("100%");
76
77        refreshButton.addClickHandler(new ClickHandler() {
78            public void onClick(ClickEvent event) {
79                getSelectedTabView().refresh();
80            }
81        });
82        otherWidgetsPanel.add(refreshButton);
83
84        autorefreshCheckbox.addValueChangeHandler(new ValueChangeHandler() {
85            public void onValueChange(ValueChangeEvent event) {
86                // Ensure Initialization.
87                if (autorefreshTimer == null)
88                    initialize();
89
90                Boolean value = autorefreshCheckbox.getValue();
91                TabView selectedTabView = tabViews.get(
92                        tabPanel.getTabBar().getSelectedTab());
93                if (selectedTabView != null)
94                    selectedTabView.setAutorefresh(value);
95                if (value) {
96                    autorefreshTimer.scheduleRepeating(AUTOREFRESH_INTERVAL);
97                } else {
98                    autorefreshTimer.cancel();
99                }
100            }
101        });
102        otherWidgetsPanel.add(autorefreshCheckbox);
103
104        CustomHistory.addHistoryListener(this);
105
106        top.setStyleName("custom-tab-top");
107        container.setStyleName("custom-tab-panel");
108        initWidget(container);
109    }
110
111    /**
112     * This must be called after this widget has been added to the page.
113     */
114    public void initialize() {
115        // if the history token didn't provide a selected tab, default to the
116        // first tab
117        if (getSelectedTabView() == null)
118            tabPanel.selectTab(0);
119        autorefreshTimer = new Timer() {
120            @Override
121            public void run() {
122                getSelectedTabView().refresh();
123            }
124        };
125    }
126
127    public void addTabView(TabView tabView) {
128        tabView.attachToDocument();
129        tabViews.add(tabView);
130        tabPanel.add(tabView.getWidget(), tabView.getTitle());
131    }
132
133    public List<TabView> getTabViews() {
134        return Collections.unmodifiableList(tabViews);
135    }
136
137    public TabView getSelectedTabView() {
138        int selectedTab = tabPanel.getTabBar().getSelectedTab();
139        if (selectedTab == -1)
140            return null;
141        return tabViews.get(selectedTab);
142    }
143
144    public void selectTabView(TabView tabView) {
145        for (int i = 0; i < tabViews.size(); i++) {
146            if (tabViews.get(i) == tabView) {
147                tabPanel.selectTab(i);
148                return;
149            }
150        }
151
152        throw new IllegalArgumentException("Tab not found");
153    }
154
155    public TabPanel getTabPanel() {
156        return tabPanel;
157    }
158
159    public Panel getOtherWidgetsPanel() {
160        return otherWidgetsPanel;
161    }
162
163    public Panel getCommonAreaPanel() {
164        return commonAreaPanel;
165    }
166
167    public void onHistoryChanged(Map<String, String> arguments) {
168        String tabId = arguments.get("tab_id");
169        if (tabId == null) {
170            return;
171        }
172
173        for (TabView tabView : tabViews) {
174            if (tabId.equals(tabView.getElementId())) {
175                tabView.ensureInitialized();
176                if (arguments.size() > 1) {
177                    // only pass along arguments if there's more than just tab_id
178                    tabView.handleHistoryArguments(arguments);
179                }
180
181                if (getSelectedTabView() != tabView) {
182                    doUpdateHistory = false;
183                    selectTabView(tabView);
184                    doUpdateHistory = true;
185                } else {
186                    tabView.display();
187                }
188
189                return;
190            }
191        }
192    }
193
194    @Override
195    public void onBeforeSelection(BeforeSelectionEvent<Integer> event) {
196        // do nothing if the user clicks the selected tab
197        if (tabPanel.getTabBar().getSelectedTab() == event.getItem())
198            event.cancel();
199        TabView selectedTabView = getSelectedTabView();
200        if (selectedTabView != null) {
201            selectedTabView.hide();
202        }
203        tabViews.get(event.getItem()).ensureInitialized();
204        tabViews.get(event.getItem()).display();
205    }
206
207    @Override
208    public void onSelection(SelectionEvent<Integer> event) {
209        TabView selectedTabView = tabViews.get(event.getSelectedItem());
210        if (doUpdateHistory)
211            selectedTabView.updateHistory();
212        // The second parameter is to fire a valueChange event if value changed.
213        autorefreshCheckbox.setValue(selectedTabView.isAutorefreshOn(), true);
214    }
215}
216