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