com.dahl.brendan.wordsearch.view.WordSearchActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.dahl.brendan.wordsearch.view.WordSearchActivity.java

Source

//    This file is part of Open WordSearch.
//
//    Open WordSearch is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    Open WordSearch 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 Open WordSearch.  If not, see <http://www.gnu.org/licenses/>.
//
//     Copyright 2009, 2010, 2011 Brendan Dahl <dahl.brendan@brendandahl.com>
//        http://www.brendandahl.com

package com.dahl.brendan.wordsearch.view;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Point;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.dahl.brendan.util.AnalyticsTask;
import com.dahl.brendan.wordsearch.Constants;
import com.dahl.brendan.wordsearch.model.HighScore;
import com.dahl.brendan.wordsearch.util.AndroidHttpClient;
import com.dahl.brendan.wordsearch.util.ConversionUtil;
import com.dahl.brendan.wordsearch.view.WordDictionaryProvider.Word;
import com.dahl.brendan.wordsearch.view.controller.TextViewGridController;
import com.dahl.brendan.wordsearch.view.controller.WordSearchActivityController;

/**
 * 
 * @author Brendan Dahl
 *
 * Activity for the word search game itself
 */
public class WordSearchActivity extends Activity {
    class StartHighScoreGlobalTask extends AsyncTask<Integer, Integer, List<HighScore>> {
        final private ProgressDialog pd = new ProgressDialog(WordSearchActivity.this);

        @Override
        protected void onPostExecute(List<HighScore> highScores) {
            if (!this.isCancelled() && pd.isShowing() && pd.getWindow() != null) {
                try {
                    pd.dismiss();
                } catch (IllegalArgumentException e) {
                    return;
                }
                if (highScores != null) {
                    StringBuilder str = new StringBuilder();
                    if (highScores.size() == 0) {
                        str.append(getString(R.string.no_high_scores));
                    } else {
                        Collections.sort(highScores);
                        for (int index = 0; index < highScores.size(); index++) {
                            str.append(Integer.toString(index + 1) + ": " + highScores.get(index).getName() + " "
                                    + highScores.get(index).getScore() + " ( "
                                    + ConversionUtil.formatTime.format(new Date(highScores.get(index).getTime()))
                                    + " )\n");
                        }
                    }
                    final DialogHighScoresGlobalShowListener DIALOG_LISTENER_HIGH_SCORES_SHOW = new DialogHighScoresGlobalShowListener();
                    AlertDialog.Builder builder = new AlertDialog.Builder(WordSearchActivity.this);
                    builder.setMessage(str);
                    builder.setTitle(R.string.GLOBAL_HIGH_SCORES);
                    builder.setNeutralButton(android.R.string.ok, DIALOG_LISTENER_HIGH_SCORES_SHOW);
                    builder.setPositiveButton(R.string.LOCAL, DIALOG_LISTENER_HIGH_SCORES_SHOW);
                    builder.show();
                } else {
                    final DialogHighScoresGlobalShowListener DIALOG_LISTENER_HIGH_SCORES_SHOW = new DialogHighScoresGlobalShowListener();
                    AlertDialog.Builder builder = new AlertDialog.Builder(WordSearchActivity.this);
                    builder.setMessage(getString(R.string.SCORE_GLOBAL_ERROR));
                    builder.setTitle(R.string.GLOBAL_HIGH_SCORES);
                    builder.setNeutralButton(android.R.string.ok, DIALOG_LISTENER_HIGH_SCORES_SHOW);
                    builder.show();
                }
            }
        }

        @Override
        protected void onPreExecute() {
            pd.setMessage(getString(R.string.LOADING));
            pd.setIndeterminate(true);
            pd.show();
        }

        @Override
        protected List<HighScore> doInBackground(Integer... res) {
            List<HighScore> results = new LinkedList<HighScore>();
            //         Debug.startMethodTracing("globalHS");
            try {
                HttpPost httpPost = new HttpPost(Constants.API_URL_SCORE_TOP10);
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                nvps.add(new BasicNameValuePair(Constants.SECURITY_TOKEN, Constants.VALUE_SECRET));
                nvps.add(new BasicNameValuePair(Constants.KEY_HIGH_SCORE_THEME, getControl().getCurrentTheme()));
                httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
                HttpResponse response = null;
                try {
                    response = httpClient.execute(httpPost);
                } catch (IllegalStateException ise) {
                    httpClient = AndroidHttpClient.newInstance("wordsearch");
                    response = httpClient.execute(httpPost);
                }
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                response.getEntity().writeTo(baos);
                JSONArray json = new JSONArray(baos.toString());
                for (int i = 0; i < json.length(); i++) {
                    results.add(new HighScore(json.getJSONObject(i)));
                }
            } catch (UnsupportedEncodingException e) {
                results = null;
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                results = null;
                e.printStackTrace();
            } catch (IOException e) {
                results = null;
                e.printStackTrace();
            } catch (JSONException e) {
                results = null;
                e.printStackTrace();
            }
            //         Debug.stopMethodTracing();
            return results;
        }
    }

    class HighScoreSubmitTask extends AsyncTask<Integer, Integer, Boolean> {
        final private HighScore hs;

        public HighScoreSubmitTask(HighScore hs) {
            this.hs = hs;
        }

        @Override
        protected Boolean doInBackground(Integer... params) {
            //         Debug.startMethodTracing("submit");
            try {
                HttpPost httpPost = new HttpPost(Constants.API_URL_SCORE_SUBMIT);
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                nvps.add(new BasicNameValuePair(Constants.SECURITY_TOKEN, Constants.VALUE_SECRET));
                nvps.add(new BasicNameValuePair(Constants.KEY_PAYLOAD, hs.toJSON().toString()));
                httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
                try {
                    httpClient.execute(httpPost);
                } catch (IllegalStateException ise) {
                    httpClient = AndroidHttpClient.newInstance("wordsearch");
                    httpClient.execute(httpPost);
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            //         Debug.stopMethodTracing();
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            getControl().clearCurrentHighScore();
        }
    }

    class DialogGameNewListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                getControl().newWordSearch();
                break;
            case DialogInterface.BUTTON_NEUTRAL:
                getControl().resetGrid();
                break;
            }
        }
    }

    class DialogGameOverListener implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
        public void onClick(DialogInterface dialog, int which) {
            String name = ((EditText) ((AlertDialog) dialog).findViewById(android.R.id.input)).getText().toString();
            HighScore hs = getControl().getCurrentHighScore();
            if (!TextUtils.isEmpty(name)) {
                hs.setName(name);
                getControl().getPrefs().setDetaultName(name);
            } else {
                hs.setName("?");
            }
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE: {
                if (!getControl().isReplaying()) {
                    new HighScoreSubmitTask(hs).execute(new Integer[0]);
                }
            }
            case DialogInterface.BUTTON_NEUTRAL: {
                LinkedList<HighScore> scores = getControl().getPrefs().getTopScores();
                scores.add(hs);
                getControl().getPrefs().setTopScores(scores);
                showDialog(WordSearchActivity.DIALOG_ID_GAME_NEW);
                break;
            }
            }
            removeDialog(DIALOG_ID_GAME_OVER);
        }

        public void onCancel(DialogInterface dialog) {
            removeDialog(DIALOG_ID_GAME_OVER);
        }
    }

    class DialogHighScoresGlobalShowListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            if (which == DialogInterface.BUTTON_NEGATIVE) {
                control.getPrefs().resetTopScores();
            }
            if (which == DialogInterface.BUTTON_POSITIVE) {
                showDialog(WordSearchActivity.DIALOG_ID_HIGH_SCORES_LOCAL_SHOW);
            } else if (!getControl().isGameRunning()) {
                showDialog(WordSearchActivity.DIALOG_ID_GAME_NEW);
            }
        }
    }

    class DialogHighScoresLocalShowListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            if (which == DialogInterface.BUTTON_NEGATIVE) {
                control.getPrefs().resetTopScores();
            }
            if (which == DialogInterface.BUTTON_POSITIVE) {
                new StartHighScoreGlobalTask().execute(new Integer[0]);
            } else if (!getControl().isGameRunning()) {
                showDialog(WordSearchActivity.DIALOG_ID_GAME_NEW);
            }
        }
    }

    class DialogNoWordsCustomListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                Intent intent = new Intent(Intent.ACTION_EDIT,
                        com.dahl.brendan.wordsearch.view.WordDictionaryProvider.Word.CONTENT_URI);
                intent.setType(com.dahl.brendan.wordsearch.view.WordDictionaryProvider.Word.CONTENT_TYPE);
                startActivity(intent);
                break;
            case DialogInterface.BUTTON_NEGATIVE:
                startActivity(new Intent(WordSearchActivity.this, WordSearchPreferences.class));
                break;
            default:
                break;
            }
        }
    }

    class DialogNoWordsListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                getControl().newWordSearch();
                break;
            case DialogInterface.BUTTON_NEUTRAL:
                startActivity(new Intent(WordSearchActivity.this, WordSearchPreferences.class));
                break;
            case DialogInterface.BUTTON_NEGATIVE:
                startActivity(new Intent(WordSearchActivity.this, WordSearchPreferences.class));
                break;
            default:
                break;
            }
        }
    }

    class DialogIntroListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE: {
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(WordSearchActivity.this);
                sp.edit().putString(getString(R.string.prefs_touch_mode), getString(R.string.TAP)).commit();
                break;
            }
            case DialogInterface.BUTTON_NEUTRAL:
                break;
            case DialogInterface.BUTTON_NEGATIVE: {
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(WordSearchActivity.this);
                sp.edit().putString(getString(R.string.prefs_touch_mode), getString(R.string.DRAG)).commit();
                break;
            }
            default:
                break;
            }
        }
    }

    class DialogDonateListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE: {
                String url = "market://details?id=com.dahl.brendan.donate";
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(url));
                startActivity(i);
                break;
            }
            case DialogInterface.BUTTON_NEUTRAL: {
                String url = "http://www.brendandahl.com/wordsearch/donate";
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(url));
                startActivity(i);
                break;
            }
            case DialogInterface.BUTTON_NEGATIVE: {
                break;
            }
            default:
                break;
            }
            control.getPrefs().setDonateIgnore();
        }
    }

    class DialogIntroDonateListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE: {
                showDialog(DIALOG_ID_DONATE);
                break;
            }
            case DialogInterface.BUTTON_NEGATIVE: {
                control.getPrefs().setDonateIgnore();
                break;
            }
            default:
                break;
            }
        }
    }

    final public static int DIALOG_ID_NO_WORDS = 0;
    final public static int DIALOG_ID_NO_WORDS_CUSTOM = 1;
    final public static int DIALOG_ID_GAME_OVER = 2;
    final public static int DIALOG_ID_HIGH_SCORES_LOCAL_SHOW = 3;
    final public static int DIALOG_ID_GAME_NEW = 5;
    final public static int DIALOG_ID_INTRO_INPUT_TYPE = 6;
    final public static int DIALOG_ID_INTRO_DONATE = 7;
    final public static int DIALOG_ID_DONATE = 8;

    final private static String LOG_TAG = "WordSearchActivity";
    /**
     * control classes were made to segment the complex game logic away from the display logic
     */
    private WordSearchActivityController control;
    private String appVer;

    public WordSearchActivityController getControl() {
        return control;
    }

    public static AndroidHttpClient httpClient = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            appVer = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
        } catch (NameNotFoundException e) {
            appVer = "unknown";
        }
        try {
            AnalyticsTask analytics = new AnalyticsTask(this, true);
            analytics.execute(new String[] { "/WordSearchActivity" });
        } catch (RuntimeException re) {
            Log.e(LOG_TAG, "tracker failed!");
        } catch (Exception e) {
            Log.e(LOG_TAG, "tracker failed!");
        }
        setContentView(R.layout.wordsearch_main);
        control = new WordSearchActivityController(this);
        control.restoreState(savedInstanceState);
        {
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
            if (!appVer.equals(sp.getString(Constants.KEY_INTRO_VER, null))
                    && sp.getString(getString(R.string.prefs_touch_mode), null) == null) {
                this.showDialog(DIALOG_ID_INTRO_INPUT_TYPE);
                sp.edit().putString(Constants.KEY_INTRO_VER, appVer).commit();
            } else if (control.getPrefs().getGamePlayCount() >= Constants.DONATE_GAME_PLAY_COUNT
                    && !control.getPrefs().isDonateIngored()) {
                this.showDialog(DIALOG_ID_INTRO_DONATE);
            }
        }
        httpClient = AndroidHttpClient.newInstance("wordsearch");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (httpClient != null) {
            httpClient.close();
        }
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        Dialog dialog;
        switch (id) {
        case DIALOG_ID_NO_WORDS: {
            final DialogNoWordsListener DIALOG_LISTENER_NO_WORDS = new DialogNoWordsListener();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.no_words);
            builder.setNegativeButton(R.string.category, DIALOG_LISTENER_NO_WORDS);
            builder.setPositiveButton(R.string.new_game, DIALOG_LISTENER_NO_WORDS);
            builder.setNeutralButton(R.string.size, DIALOG_LISTENER_NO_WORDS);
            dialog = builder.create();
            break;
        }
        case DIALOG_ID_NO_WORDS_CUSTOM: {
            final DialogNoWordsCustomListener DIALOG_LISTENER_NO_WORDS_CUSTOM = new DialogNoWordsCustomListener();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.no_words_custom);
            builder.setNegativeButton(R.string.category, DIALOG_LISTENER_NO_WORDS_CUSTOM);
            builder.setPositiveButton(R.string.custom_editor, DIALOG_LISTENER_NO_WORDS_CUSTOM);
            dialog = builder.create();
            break;
        }
        case DIALOG_ID_GAME_OVER: {
            final DialogGameOverListener DIALOG_LISTENER_GAME_OVER = new DialogGameOverListener();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("blank");
            EditText text = new EditText(this);
            text.setSingleLine();
            text.setId(android.R.id.input);
            builder.setView(text);
            builder.setPositiveButton(R.string.SAVE_SUBMIT, DIALOG_LISTENER_GAME_OVER);
            builder.setNeutralButton(R.string.SAVE, DIALOG_LISTENER_GAME_OVER);
            builder.setOnCancelListener(DIALOG_LISTENER_GAME_OVER);
            dialog = builder.create();
            break;
        }
        case DIALOG_ID_HIGH_SCORES_LOCAL_SHOW: {
            final DialogHighScoresLocalShowListener DIALOG_LISTENER_HIGH_SCORES_SHOW = new DialogHighScoresLocalShowListener();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("blank");
            builder.setTitle(R.string.LOCAL_HIGH_SCORES);
            builder.setNegativeButton(R.string.reset, DIALOG_LISTENER_HIGH_SCORES_SHOW);
            builder.setNeutralButton(android.R.string.ok, DIALOG_LISTENER_HIGH_SCORES_SHOW);
            builder.setPositiveButton(R.string.GLOBAL, DIALOG_LISTENER_HIGH_SCORES_SHOW);
            dialog = builder.create();
            break;
        }
        case DIALOG_ID_GAME_NEW: {
            final DialogGameNewListener DIALOG_LISTENER_GAME_NEW = new DialogGameNewListener();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(this.getString(R.string.game_over));
            builder.setPositiveButton(R.string.new_game, DIALOG_LISTENER_GAME_NEW);
            builder.setNeutralButton(R.string.REPLAY, DIALOG_LISTENER_GAME_NEW);
            builder.setNegativeButton(android.R.string.cancel, DIALOG_LISTENER_GAME_NEW);
            dialog = builder.create();
            break;
        }
        case DIALOG_ID_INTRO_INPUT_TYPE: {
            final DialogIntroListener DIALOG_LISTENER_INTRO = new DialogIntroListener();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.INTRO);
            builder.setPositiveButton(R.string.tap, DIALOG_LISTENER_INTRO);
            builder.setNeutralButton(android.R.string.cancel, DIALOG_LISTENER_INTRO);
            builder.setNegativeButton(R.string.drag, DIALOG_LISTENER_INTRO);
            dialog = builder.create();
            break;
        }
        case DIALOG_ID_INTRO_DONATE: {
            final DialogInterface.OnClickListener LISTENER = new DialogIntroDonateListener();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.INTRO_DONATE_MSG);
            builder.setPositiveButton(R.string.DONATE, LISTENER);
            builder.setNegativeButton(R.string.DONATE_NO, LISTENER);
            dialog = builder.create();
            break;
        }
        case DIALOG_ID_DONATE: {
            final DialogInterface.OnClickListener LISTENER = new DialogDonateListener();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.DONATE_MSG);
            builder.setPositiveButton(R.string.DONATE_MARKET, LISTENER);
            builder.setNeutralButton(R.string.DONATE_WEB, LISTENER);
            builder.setNegativeButton(R.string.DONATE_NO, LISTENER);
            dialog = builder.create();
            break;
        }
        default:
            dialog = super.onCreateDialog(id);
            break;
        }
        return dialog;
    }

    /** hook into menu button for activity */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        this.getMenuInflater().inflate(R.menu.wordsearch_options, menu);
        menu.findItem(R.id.menu_new).setIcon(android.R.drawable.ic_menu_add);
        menu.findItem(R.id.menu_options).setIcon(android.R.drawable.ic_menu_preferences);
        menu.findItem(R.id.menu_custom).setIcon(android.R.drawable.ic_menu_edit);
        menu.findItem(R.id.menu_tutorial).setIcon(android.R.drawable.ic_menu_help);
        menu.findItem(R.id.menu_scores).setIcon(android.R.drawable.ic_menu_gallery);
        menu.findItem(R.id.menu_donate).setIcon(R.drawable.love);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    protected void onPrepareDialog(int id, Dialog dialog) {
        super.onPrepareDialog(id, dialog);
        switch (id) {
        case DIALOG_ID_GAME_OVER: {
            HighScore hs = control.getCurrentHighScore();
            TextView label = (TextView) ((AlertDialog) dialog).findViewById(android.R.id.message);
            String msg = this.getString(R.string.SCORE_CONGRATULATIONS).replace("%replaceme",
                    hs.getScore().toString() + " (" + ConversionUtil.formatTime.format(new Date(hs.getTime()))
                            + ")");
            if (hs.isHighScore()) {
                msg += this.getString(R.string.SCORE_LOCAL_HIGH).replace("%replaceme",
                        Integer.toString(hs.getRank() + 1));
            }
            if (hs.isGlobalError()) {
                msg += this.getString(R.string.SCORE_GLOBAL_ERROR);
            } else {
                String global = "";
                if (hs.isGlobalHighScore()) {
                    global = this.getString(R.string.SCORE_GLOBAL_HIGH);
                } else {
                    global = this.getString(R.string.SCORE_GLOBAL_PERCENT);
                }
                msg += global.replace("%replaceme", Integer.toString(hs.getGlobalRank()));
            }
            EditText edit = (EditText) ((AlertDialog) dialog).findViewById(android.R.id.input);
            Button save = (Button) ((AlertDialog) dialog).findViewById(android.R.id.button3);
            edit.setText(getControl().getPrefs().getDefaultName());
            if (hs.isHighScore()) {
                save.setVisibility(EditText.VISIBLE);
            } else {
                save.setVisibility(EditText.GONE);
            }
            if (hs.isHighScore() || !hs.isGlobalError()) {
                edit.setVisibility(EditText.VISIBLE);
                msg += this.getString(R.string.SCORE_INITIALS);
            } else {
                edit.setVisibility(EditText.GONE);
            }
            label.setText(msg);
            break;
        }
        case DIALOG_ID_HIGH_SCORES_LOCAL_SHOW: {
            //         Debug.startMethodTracing("localHS");
            List<HighScore> highScores = this.getControl().getHighScores();
            StringBuilder str = new StringBuilder();
            if (highScores.size() == 0) {
                str.append(this.getString(R.string.no_high_scores));
            } else {
                Collections.sort(highScores);
                for (int index = 0; index < highScores.size(); index++) {
                    str.append(Integer.toString(index + 1) + ": " + highScores.get(index).getName() + " "
                            + highScores.get(index).getScore() + " ( "
                            + ConversionUtil.formatTime.format(new Date(highScores.get(index).getTime())) + " )\n");
                }
            }
            TextView label = (TextView) ((AlertDialog) dialog).findViewById(android.R.id.message);
            label.setText(str);
            //         Debug.stopMethodTracing();
            break;
        }
        default:
            break;
        }
    }

    /** when menu button option selected */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_scores:
            this.showDialog(DIALOG_ID_HIGH_SCORES_LOCAL_SHOW);
            return true;
        case R.id.menu_options:
            startActivity(new Intent(this, WordSearchPreferences.class));
            return true;
        case R.id.menu_new:
            control.newWordSearch();
            return true;
        case R.id.menu_custom: {
            Intent intent = new Intent(Intent.ACTION_EDIT, Word.CONTENT_URI);
            intent.setType(Word.CONTENT_TYPE);
            this.startActivity(intent);
            return true;
        }
        case R.id.menu_tutorial: {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setClass(this, TutorialActivity.class);
            startActivity(intent);
            return true;
        }
        case R.id.menu_donate: {
            this.showDialog(DIALOG_ID_DONATE);
            return true;
        }
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        //      Log.v(LOG_TAG, "onPause");
        control.timePause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //      Log.v(LOG_TAG, "onResume");
        if (control.isGameRunning()) {
            control.timeResume();
        } else if (control.getCurrentHighScore() != null) {
            showDialog(WordSearchActivity.DIALOG_ID_GAME_OVER);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //      Log.v(LOG_TAG, "onSaveInstanceState");
        control.saveState(outState);
        this.removeDialog(DIALOG_ID_GAME_OVER);
    }

    /**
     * creates a grid of textViews from layout files based on the gridSize
     *  and sets the new textViews to use the controller as their listener
     * 
     * @param gridSize square size of the new grid to make
     * @param controller the onkeyListener used for the grid's textViews, also holds the gridView an array of the new textView's in the grid
     */
    public void setupViewGrid() {
        control.setLetter(null);
        int gridSize = control.getGridSize();
        TextViewGridController controller = control.getGridManager();
        ViewGroup gridTable = (ViewGroup) this.findViewById(R.id.gridTable);
        if (gridTable.getChildCount() != gridSize) {
            if (gridTable.getChildCount() == 0) {
                gridTable.setKeepScreenOn(true);
                gridTable.setOnTouchListener(controller);
            }
            controller.clearPointDemension();
            gridTable.removeAllViews();
            Point point = new Point();
            controller.setGridView(new TextView[gridSize][]);
            TextView[][] gridView = controller.getGridView();
            for (point.y = 0; point.y < gridSize; point.y++) {
                this.getLayoutInflater().inflate(R.layout.grid_row, gridTable, true);
                ViewGroup row = (ViewGroup) gridTable.getChildAt(point.y);
                TextView[] rowText = new TextView[gridSize];
                for (point.x = 0; point.x < gridSize; point.x++) {
                    this.getLayoutInflater().inflate(R.layout.grid_text_view, row, true);
                    TextView view = (TextView) row.getChildAt(point.x);
                    view.setId(ConversionUtil.convertPointToID(point, control.getGridSize()));
                    view.setOnKeyListener(controller);

                    rowText[point.x] = view;
                }
                gridView[point.y] = rowText;
            }
            gridTable.requestLayout();
        }
    }

    public void trackGame() {
        try {
            String category = control.getPrefs().getCategory();
            String input = "Tap";
            if (control.getPrefs().getTouchMode()) {
                input = "Drag";
            }
            AnalyticsTask analytics = new AnalyticsTask(this, false);
            analytics.execute(new String[] { category, input, Integer.toString(control.getGridSize()) });
        } catch (RuntimeException re) {
            Log.e(LOG_TAG, "tracker failed!");
        } catch (Exception e) {
            Log.e(LOG_TAG, "tracker failed!");
        }
    }

    public void trackReplay() {
        try {
            String category = control.getPrefs().getCategory();
            AnalyticsTask analytics = new AnalyticsTask(this, false);
            analytics.execute(new String[] { category, "replay", Integer.toString(control.getGridSize()) });
        } catch (RuntimeException re) {
            Log.e(LOG_TAG, "tracker failed!");
        } catch (Exception e) {
            Log.e(LOG_TAG, "tracker failed!");
        }
    }
}