bingo.client.Bingo.java Source code

Java tutorial

Introduction

Here is the source code for bingo.client.Bingo.java

Source

/*******************************************************************************
 *  This file is part of Bad Presentation Bingo.
 *
 *  Bad Presentation Bingo is free software: you can redistribute it and/or 
 *  modify it under the terms of the GNU General Public License verion 3
 *  as published by the Free Software Foundation
 *
 *  Bad Presentation Bingo is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *    Javier Canovas (http://jlcanovas.es) 
 *******************************************************************************/

package bingo.client;

import java.util.Date;

import bingo.client.resources.BingoResources;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Main entry point class: the landing page.
 */
public class Bingo implements EntryPoint {
    // Cookie identifier
    public final static String COOKIE_ID = "bingo-bad-presentation";
    // Set the value of the hours mesaure of the expiration date of the cookie
    public final static int EXPIRATION_VALUE = 2;

    // Timer used to refresh in admin view
    public final static int ADMIN_TIMER = 1000;
    // Timer used to refresh in user view
    public final static int USER_TIMER = 1000;

    /**
     * Keeps the userId (managed by cookies)
     */
    String userId = null;

    /**
     * Support for i18n
     */
    final BingoStrings strings = (BingoStrings) GWT.create(BingoStrings.class);

    /**
     * Easy way to show messages to the user
     */
    final HTML message = new HTML("Loading...");

    /**
     * Create a remote service proxy to talk to the server-side Bingo service.
     */
    private final BingoServiceAsync bingoService = GWT.create(BingoService.class);

    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {
        Label titleLabel = new Label();
        titleLabel.setText(strings.title());
        RootPanel.get("title").add(titleLabel);

        // This is the general notification text box
        RootPanel.get("message").add(message);

        // Cheking if the user has already an user id
        final String cookie = Cookies.getCookie(COOKIE_ID);

        // Validating the cookie
        bingoService.statusUserId(cookie, new AsyncCallback<Integer>() {
            @Override
            public void onFailure(Throwable caught) {
                message.setText(caught.getMessage());
                Cookies.removeCookie(COOKIE_ID);
            }

            @Override
            public void onSuccess(Integer status) {
                // TODO: Control the logged status (I should not get a user if s/he is already logged)
                if (status.intValue() == BingoService.NO_LOGGED || status.intValue() == BingoService.LOGGED) {
                    bingoService.getUserId(new AsyncCallback<String>() {
                        @Override
                        public void onFailure(Throwable caught) {
                            message.setText(strings.errorUserCreation());
                        }

                        @Override
                        public void onSuccess(String result) {
                            userId = result;
                        }
                    });

                    message.setHTML("");

                    // Showing image to enter
                    ImageResource imageResource = BingoResources.INSTANCE.entry();
                    Image entryImage = new Image(imageResource.getSafeUri());
                    RootPanel.get("buttons").add(entryImage);

                    // Selecting behavior (admin / voter) 
                    HorizontalPanel entryPoint = new HorizontalPanel();

                    entryPoint.setStyleName("mainSelectorPanel");
                    entryPoint.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
                    entryPoint.setSpacing(50);

                    // 
                    // CREATING A BINGO
                    //
                    VerticalPanel leftPanel = new VerticalPanel();
                    leftPanel.setStyleName("selectorPanel");

                    Label leftPanelTitle = new Label();
                    leftPanelTitle.setStyleName("selectorPanelTitle");
                    leftPanelTitle.setText(strings.leftPanelTitle());
                    leftPanel.add(leftPanelTitle);
                    leftPanel.setCellHorizontalAlignment(leftPanelTitle, HasHorizontalAlignment.ALIGN_CENTER);

                    Grid leftSubPanel = new Grid(2, 2);
                    leftSubPanel.setWidget(0, 0, new Label(strings.createBingoName()));
                    final TextBox bingoNameBox = new TextBox();
                    leftSubPanel.setWidget(0, 1, bingoNameBox);

                    leftSubPanel.setWidget(1, 0, new Label(strings.createBingoPassword()));
                    final PasswordTextBox bingoPasswordBox = new PasswordTextBox();
                    leftSubPanel.setWidget(1, 1, bingoPasswordBox);
                    leftPanel.add(leftSubPanel);

                    final Button createButton = new Button("Create");
                    createButton.addClickHandler(new ClickHandler() {
                        public void onClick(ClickEvent event) {
                            bingoService.createBingo(userId, bingoNameBox.getText(), bingoPasswordBox.getText(),
                                    new AsyncCallback<String>() {
                                        @Override
                                        public void onFailure(Throwable caught) {
                                            message.setText(caught.getMessage());
                                        }

                                        @Override
                                        public void onSuccess(final String gameId) {
                                            final BingoGrid bingoGrid = new BingoGrid();
                                            initAdminGrid(userId, bingoGrid, false);
                                            RootPanel.get("bingoTable").clear();
                                            RootPanel.get("bingoTable").add(bingoGrid);
                                            message.setText(strings.welcomeMessageCreation());

                                            // Setting the cookie
                                            Date expirationDate = new Date();
                                            expirationDate.setHours(expirationDate.getHours() + EXPIRATION_VALUE);
                                            Cookies.setCookie(COOKIE_ID, userId, expirationDate);
                                        }
                                    });
                        }
                    });
                    leftPanel.add(createButton);
                    leftPanel.setCellHorizontalAlignment(createButton, HasHorizontalAlignment.ALIGN_CENTER);
                    entryPoint.add(leftPanel);

                    // 
                    // JOINING
                    //
                    VerticalPanel rightPanel = new VerticalPanel();
                    rightPanel.setStyleName("selectorPanel");

                    Label rightPanelTitle = new Label();
                    rightPanelTitle.setStyleName("selectorPanelTitle");
                    rightPanelTitle.setText(strings.rightPanelTitle());
                    rightPanel.add(rightPanelTitle);
                    rightPanel.setCellHorizontalAlignment(rightPanelTitle, HasHorizontalAlignment.ALIGN_CENTER);

                    Grid rightSubPanel = new Grid(2, 2);
                    rightSubPanel.setWidget(0, 0, new Label(strings.joinToBingoName()));
                    final ListBox joinExistingBingoBox = new ListBox();
                    bingoService.getBingos(new AsyncCallback<String[][]>() {
                        @Override
                        public void onFailure(Throwable caught) {
                            joinExistingBingoBox.addItem(strings.noBingos());
                        }

                        @Override
                        public void onSuccess(String[][] result) {
                            if (result == null) {
                                joinExistingBingoBox.addItem(strings.noBingos());
                            } else {
                                for (int i = 0; i < result.length; i++) {
                                    String gameName = result[i][0];
                                    String gameId = result[i][1];
                                    joinExistingBingoBox.addItem(gameName, gameId);
                                }
                            }
                        }
                    });
                    rightSubPanel.setWidget(0, 1, joinExistingBingoBox);

                    rightSubPanel.setWidget(1, 0, new Label(strings.joinToBingoPassword()));
                    final PasswordTextBox joinBingoPasswordBox = new PasswordTextBox();
                    rightSubPanel.setWidget(1, 1, joinBingoPasswordBox);
                    rightPanel.add(rightSubPanel);

                    final Button joinButton = new Button("Join");
                    joinButton.addClickHandler(new ClickHandler() {
                        public void onClick(ClickEvent event) {
                            int index = joinExistingBingoBox.getSelectedIndex();
                            if (index < 0)
                                message.setText(strings.noSelectedItem());
                            else {
                                final String gameId = joinExistingBingoBox.getValue(index);
                                if (gameId == null)
                                    message.setText(strings.noSelectedItem());
                                else {
                                    bingoService.joinBingo(userId, gameId, joinBingoPasswordBox.getText(),
                                            new AsyncCallback<Void>() {
                                                @Override
                                                public void onFailure(Throwable caught) {
                                                    message.setText(caught.getMessage());
                                                }

                                                @Override
                                                public void onSuccess(Void result) {
                                                    final BingoGrid bingoGrid = new BingoGrid();
                                                    initUserGrid(bingoGrid);
                                                    RootPanel.get("bingoTable").clear();
                                                    RootPanel.get("bingoTable").add(bingoGrid);

                                                    message.setText(strings.welcomeMessageJoin());

                                                    // Setting the cookie
                                                    Date expirationDate = new Date();
                                                    expirationDate
                                                            .setHours(expirationDate.getHours() + EXPIRATION_VALUE);
                                                    Cookies.setCookie(COOKIE_ID, userId, expirationDate);
                                                }
                                            });
                                }
                            }
                        }
                    });
                    rightPanel.add(joinButton);
                    rightPanel.setCellHorizontalAlignment(joinButton, HasHorizontalAlignment.ALIGN_CENTER);
                    entryPoint.add(rightPanel);

                    RootPanel.get("bingoTable").add(entryPoint);

                } else if (status.intValue() == BingoService.ADMIN) {
                    message.setText("Detected cookie: " + cookie + " as admin");
                    userId = cookie;

                    bingoService.statusBingo(userId, new AsyncCallback<Integer>() {
                        @Override
                        public void onFailure(Throwable caught) {
                            message.setText(caught.getMessage());
                        }

                        @Override
                        public void onSuccess(Integer result) {
                            int status = result.intValue();
                            final BingoGrid bingoGrid = new BingoGrid();
                            if (status == BingoService.RUNNING) {
                                initAdminGrid(userId, bingoGrid, false);
                                message.setText(strings.welcomeMessageCreation());
                            } else if (status == BingoService.FINISHED) {
                                initAdminGrid(userId, bingoGrid, true);
                                message.setText(strings.finishMessage());
                            }
                            RootPanel.get("bingoTable").clear();
                            RootPanel.get("bingoTable").add(bingoGrid);
                        }
                    });

                } else if (status.intValue() == BingoService.PARTICIPANT) {
                    message.setText("Detected cookie: " + cookie + " as participant");
                    userId = cookie;

                    final BingoGrid bingoGrid = new BingoGrid();
                    initUserGrid(bingoGrid);
                    updateUserGrid(bingoGrid, null);
                    RootPanel.get("bingoTable").clear();
                    RootPanel.get("bingoTable").add(bingoGrid);
                }
            }
        });
    }

    private void initAdminGrid(final String userId, final BingoGrid bingoGrid, final boolean hasFinished) {
        final Timer timer = new Timer() {
            int totalParticipants = 0;

            @Override
            public void run() {
                bingoService.getTotalParticipants(userId, new AsyncCallback<Integer>() {
                    @Override
                    public void onFailure(Throwable caught) {
                    }

                    @Override
                    public void onSuccess(Integer result) {
                        totalParticipants = result.intValue();
                    }
                });

                bingoService.getVotes(userId, new AsyncCallback<int[][]>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        message.setText(caught.getMessage());
                    }

                    @Override
                    public void onSuccess(int[][] result) {
                        if (result == null) {
                            result = new int[BingoGrid.ROW][BingoGrid.COL];
                            for (int i = 0; i < BingoGrid.ROW; i++)
                                for (int j = 0; j < BingoGrid.COL; j++)
                                    result[i][j] = 0;
                        }

                        for (int row = 0; row < BingoGrid.ROW; ++row)
                            for (int col = 0; col < BingoGrid.COL; ++col) {
                                bingoGrid.setVoteString(row, col, String.valueOf(result[row][col]),
                                        String.valueOf(totalParticipants));
                            }
                    }
                });
            }
        };

        // If the game is not finished, repeat; if so, run once
        if (!hasFinished)
            timer.scheduleRepeating(ADMIN_TIMER);
        else
            timer.run();

        HorizontalPanel panel = new HorizontalPanel();
        panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        final Button finishButton = new Button();

        // If the game is not finished, allow finishing it; if so, allow download data
        if (!hasFinished)
            finishButton.setText(strings.finishBingo());
        else
            finishButton.setText(strings.download());

        finishButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                if (!hasFinished)
                    bingoService.finishBingo(userId, new AsyncCallback<Void>() {
                        @Override
                        public void onFailure(Throwable caught) {
                            message.setText(caught.getMessage());
                        }

                        @Override
                        public void onSuccess(Void result) {
                            message.setText(strings.finishedBingo());
                            finishButton.setText(strings.download());
                            timer.cancel();
                        }
                    });

                bingoService.getVotes(userId, new AsyncCallback<int[][]>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        message.setText(caught.getMessage());
                    }

                    @Override
                    public void onSuccess(int[][] result) {
                        // Create a popup dialog box
                        final DialogBox box = new DialogBox();
                        box.setText(strings.info());
                        box.setAnimationEnabled(true);

                        final Button boxAcceptButton = new Button(strings.accept());
                        boxAcceptButton.addClickHandler(new ClickHandler() {
                            @Override
                            public void onClick(ClickEvent event) {
                                box.hide();
                            }
                        });

                        Label boxLabel = new Label();
                        boxLabel.setText(strings.finishMessage());
                        HTML voteData = new HTML();
                        if (result == null) {
                            result = new int[BingoGrid.ROW][BingoGrid.COL];
                            for (int i = 0; i < BingoGrid.ROW; i++)
                                for (int j = 0; j < BingoGrid.COL; j++)
                                    result[i][j] = 0;
                        }

                        String cellKey = "";
                        String cellString = "";
                        String voteDataString = "";
                        for (int row = 0; row < BingoGrid.ROW; ++row)
                            for (int col = 0; col < BingoGrid.COL; ++col) {
                                cellKey = "cell" + row + col;
                                cellString = strings.map().get(cellKey);
                                voteDataString += "&nbsp;&nbsp;&nbsp;" + cellString + " = " + result[row][col]
                                        + "<br>";
                            }
                        voteData.setHTML(voteDataString);
                        voteData.addStyleName("boxData");

                        VerticalPanel boxPanel = new VerticalPanel();
                        boxPanel.addStyleName("boxPanel");
                        boxPanel.add(boxLabel);
                        boxPanel.add(voteData);

                        HorizontalPanel buttonsPanel = new HorizontalPanel();
                        buttonsPanel.add(boxAcceptButton);
                        boxPanel.add(buttonsPanel);
                        boxPanel.setCellHorizontalAlignment(buttonsPanel, HasHorizontalAlignment.ALIGN_CENTER);

                        box.setWidget(boxPanel);
                        box.center();
                    }
                });
            }
        });
        panel.add(finishButton);

        final Button terminateButton = new Button(strings.terminateButton());
        terminateButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                // Create a popup dialog box
                final DialogBox box = new DialogBox();
                box.setText(strings.warning());
                box.setAnimationEnabled(true);

                final Button boxCancelButton = new Button(strings.cancel());
                boxCancelButton.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        box.hide();
                    }
                });
                final Button boxAcceptButton = new Button(strings.accept());
                boxAcceptButton.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        bingoService.terminateBingo(userId, new AsyncCallback<Void>() {
                            @Override
                            public void onFailure(Throwable caught) {
                                message.setText(caught.getMessage());
                            }

                            @Override
                            public void onSuccess(Void result) {
                                message.setText(strings.terminatedBingo());
                                timer.cancel();
                            }

                        });
                        box.hide();
                    }
                });

                final Label boxLabel = new Label();
                boxLabel.setText(strings.terminateMessage());

                VerticalPanel boxPanel = new VerticalPanel();

                boxPanel.addStyleName("boxPanel");
                boxPanel.add(boxLabel);

                HorizontalPanel buttonsPanel = new HorizontalPanel();
                buttonsPanel.add(boxCancelButton);
                buttonsPanel.add(boxAcceptButton);
                boxPanel.add(buttonsPanel);

                box.setWidget(boxPanel);
                box.center();
            }
        });
        panel.add(terminateButton);

        RootPanel.get("buttons").clear();
        RootPanel.get("buttons").add(panel);
    }

    private void initUserGrid(final BingoGrid bingoGrid) {
        bingoGrid.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                Cell cell = bingoGrid.getCellForEvent(event);
                if (cell != null) {
                    final int row = cell.getRowIndex();
                    final int col = cell.getCellIndex();
                    if (!bingoGrid.cellHasBeenVoted(row, col)) {
                        bingoGrid.voteForCell(row, col);

                        bingoService.voteCell(userId, row, col, new AsyncCallback<Long>() {
                            @Override
                            public void onFailure(Throwable caught) {
                                message.setText(strings.errorUserVote());
                                bingoGrid.voteAgainstCell(row, col);
                            }

                            @Override
                            public void onSuccess(Long result) {
                                // For now, no control of lines completed
                                //                        bingoGrid.colorLines(result);
                            }
                        });
                    } else {
                        message.setText(strings.alreadyVoted());
                    }
                }
            }
        });

        Timer timer = new Timer() {
            @Override
            public void run() {
                updateUserGrid(bingoGrid, this);
            }
        };

        timer.scheduleRepeating(USER_TIMER);

        RootPanel.get("buttons").clear();
    }

    private void updateUserGrid(final BingoGrid bingoGrid, final Timer timer) {
        bingoService.statusBingoVotes(userId, new AsyncCallback<boolean[][]>() {
            @Override
            public void onFailure(Throwable caught) {
                message.setText(strings.errorUserSynchronization());
                if (timer != null)
                    timer.cancel();
            }

            @Override
            public void onSuccess(boolean[][] result) {
                bingoGrid.colorVotes(result);
            }
        });

        // For now, no control of lines completed
        //      bingoService.statusBingoLines(userId, new AsyncCallback<Long>() {
        //         @Override
        //         public void onFailure(Throwable caught) {
        //            message.setText(strings.errorUserSynchronization());
        //            if(timer != null) timer.cancel();
        //         }
        //         @Override
        //         public void onSuccess(Long result) {
        //            bingoGrid.colorLines(result);
        //         }
        //      });
    }

}