org.nla.tarotdroid.lib.ui.GameSetHistoryActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.nla.tarotdroid.lib.ui.GameSetHistoryActivity.java

Source

/*
   This file is part of the Android application TarotDroid.
    
   TarotDroid 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.
    
TarotDroid 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 TarotDroid. If not, see <http://www.gnu.org/licenses/>.
 */
package org.nla.tarotdroid.lib.ui;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.nla.tarotdroid.lib.ui.tasks.RemoveGameSetTask;
import org.nla.tarotdroid.lib.R;
import org.nla.tarotdroid.lib.app.AppContext;
import org.nla.tarotdroid.biz.GameSet;
import org.nla.tarotdroid.dal.DalException;
import org.nla.tarotdroid.lib.helpers.AuditHelper;
import org.nla.tarotdroid.lib.helpers.AuditHelper.ErrorTypes;
import org.nla.tarotdroid.lib.helpers.AuditHelper.EventTypes;
import org.nla.tarotdroid.lib.helpers.BluetoothHelper;
import org.nla.tarotdroid.lib.helpers.FacebookHelper;
import org.nla.tarotdroid.lib.helpers.UIHelper;
import org.nla.tarotdroid.lib.ui.constants.ActivityParams;
import org.nla.tarotdroid.lib.ui.constants.RequestCodes;
import org.nla.tarotdroid.lib.ui.controls.ThumbnailItem;
import org.nla.tarotdroid.lib.ui.tasks.ExportToExcelTask;
import org.nla.tarotdroid.lib.ui.tasks.IAsyncCallback;
import org.nla.tarotdroid.lib.ui.tasks.PostGameSetLinkOnFacebookWallTask;
import org.nla.tarotdroid.lib.ui.tasks.ReceiveGameSetTask;
import org.nla.tarotdroid.lib.ui.tasks.RemoveAllGameSetsTask;
import org.nla.tarotdroid.lib.ui.tasks.SendGameSetTask;
import org.nla.tarotdroid.lib.ui.tasks.UpSyncGameSetTask;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockListActivity;
import com.actionbarsherlock.view.MenuItem.OnMenuItemClickListener;
import com.actionbarsherlock.view.SubMenu;
import com.facebook.FacebookRequestError;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphUser;
import com.google.common.base.Charsets;

/**
 * Displays all the stored game sets.
 * 
 * @author Nicolas LAURENT daffycricket<a>yahoo.fr
 */
@TargetApi(Build.VERSION_CODES.CUPCAKE)
public class GameSetHistoryActivity extends SherlockListActivity {

    /**
     * A listener to transfer a game set to a selected bluetooth device.
     */
    private class BluetoothDeviceClickListener implements DialogInterface.OnClickListener {

        /**
         * The device names towards which to send the GameSet.
         */
        private final String[] bluetoothDeviceNames;

        /**
         * The GameSet to transfer.
         */
        private final GameSet gameSet;

        /**
         * Constructor.
         * 
         * @param gameSet
         * @param bluetoothDeviceNames
         */
        public BluetoothDeviceClickListener(final GameSet gameSet, final String[] bluetoothDeviceNames) {
            this.gameSet = gameSet;
            this.bluetoothDeviceNames = bluetoothDeviceNames;
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * android.content.DialogInterface.OnClickListener#onClick(android.content
         * .DialogInterface, int)
         */
        @Override
        public void onClick(final DialogInterface dialog, final int which) {
            AuditHelper.auditEvent(AuditHelper.EventTypes.actionBluetoothSendGameSet);
            GameSetHistoryActivity.this.sendGameSetOverBluetooth(this.gameSet,
                    GameSetHistoryActivity.this.bluetoothHelper
                            .getBluetoothDevice(this.bluetoothDeviceNames[which]));
        }
    }

    /**
     * Internal adapter to back up the list.
     */
    private class GameSetAdapter extends ArrayAdapter<GameSet> {

        /**
         * Constructs a GameSetAdapter.
         * 
         * @param context
         * @param gameSets
         */
        public GameSetAdapter(Context context, List<GameSet> gameSets) {
            super(context, R.layout.thumbnail_item, gameSets);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            GameSet gameSet = this.getItem(position);

            int drawableId;
            switch (gameSet.getGameStyleType()) {
            case Tarot3:
                if (gameSet.getFacebookPostTs() != null) {
                    drawableId = R.drawable.icon_3players_facebook;
                } else {
                    drawableId = R.drawable.icon_3players;
                }
                break;
            case Tarot4:
                if (gameSet.getFacebookPostTs() != null) {
                    drawableId = R.drawable.icon_4players_facebook;
                } else {
                    drawableId = R.drawable.icon_4players;
                }
                break;
            case Tarot5:
                if (gameSet.getFacebookPostTs() != null) {
                    drawableId = R.drawable.icon_5players_facebook;
                } else {
                    drawableId = R.drawable.icon_5players;
                }
                break;
            case None:
            default:
                throw new IllegalStateException("unknown gameSet type: " + gameSet.getGameStyleType());
            }

            ThumbnailItem thumbnailItem = new ThumbnailItem(this.getContext(), drawableId,
                    UIHelper.buildGameSetHistoryTitle(gameSet), UIHelper.buildGameSetHistoryDescription(gameSet));

            return thumbnailItem;
        }
    }

    /**
     * A list item.
     */
    private static class Item {

        protected enum ItemTypes {
            edit, exportToExcel, publishOnFacebook, publishOnTwitter, remove, transferOverBluetooth
        };

        public final int icon;

        public final ItemTypes itemType;

        public final String text;

        public Item(String text, Integer icon, ItemTypes itemType) {
            this.text = text;
            this.icon = icon;
            this.itemType = itemType;
        }

        @Override
        public String toString() {
            return text;
        }
    }

    /**
     * Facebook post response.
     */
    private interface PostResponse extends GraphObject {
        String getId();
    }

    /**
     * A listener to delete a game set.
     */
    private class RemoveGameSetDialogClickListener implements DialogInterface.OnClickListener {

        /**
         * The GameSet to transfer.
         */
        private final GameSet gameSet;

        /**
         * Constructor.
         * 
         * @param gameSet
         */
        public RemoveGameSetDialogClickListener(final GameSet gameSet) {
            this.gameSet = gameSet;
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * android.content.DialogInterface.OnClickListener#onClick(android.content
         * .DialogInterface, int)
         */
        @Override
        public void onClick(final DialogInterface dialog, final int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                RemoveGameSetTask removeGameSetTask = new RemoveGameSetTask(GameSetHistoryActivity.this,
                        GameSetHistoryActivity.this.progressDialog, this.gameSet);
                removeGameSetTask.setCallback(refreshCallback);
                removeGameSetTask.execute();
                break;

            case DialogInterface.BUTTON_NEGATIVE:
            default:
                break;
            }
        }
    }

    /**
     * Items for non limited app.
     */
    private static final Item[] allItems = {
            new Item(AppContext.getApplication().getResources().getString(R.string.lblPublishGameSet),
                    R.drawable.facebook_white, Item.ItemTypes.publishOnFacebook),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblPublishGameSet),
                    R.drawable.facebook_white, Item.ItemTypes.publishOnTwitter),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblEditGameSet),
                    android.R.drawable.ic_menu_edit, Item.ItemTypes.edit),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblDeleteGameSet),
                    R.drawable.gd_action_bar_trashcan, Item.ItemTypes.remove),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblBluetoothSend),
                    R.drawable.stat_sys_data_bluetooth, Item.ItemTypes.transferOverBluetooth),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblExcelExport),
                    R.drawable.ic_excel, Item.ItemTypes.exportToExcel), };

    /**
     * Comparator of gamesets based upon their creation dates.
     */
    private static final Comparator<GameSet> gameSetCreationDateDescendingComparator = new Comparator<GameSet>() {

        /*
         * (non-Javadoc)
         * 
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        @Override
        public int compare(final GameSet arg0, final GameSet arg1) {
            return (arg1.getCreationTs().compareTo(arg0.getCreationTs()));
        }
    };

    /**
     * Items for limited app.
     */
    private static final Item[] limitedItems = {
            new Item(AppContext.getApplication().getResources().getString(R.string.lblPublishGameSet),
                    R.drawable.facebook_white, Item.ItemTypes.publishOnFacebook),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblPublishGameSet),
                    R.drawable.facebook_white, Item.ItemTypes.publishOnTwitter),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblEditGameSet),
                    android.R.drawable.ic_menu_edit, Item.ItemTypes.edit),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblDeleteGameSet),
                    R.drawable.gd_action_bar_trashcan, Item.ItemTypes.remove),
            new Item(AppContext.getApplication().getResources().getString(R.string.lblBluetoothSend),
                    R.drawable.stat_sys_data_bluetooth, Item.ItemTypes.transferOverBluetooth) };

    /**
     * Key used in storing the pendingReauthRequest flag
     */
    private static final String PENDING_REAUTH_KEY = "pendingReauthRequest";

    /**
     * List of additional write permissions being requested
     */
    private static final List<String> PUBLISH_PERMISSIONS = Arrays.asList("publish_actions");

    /**
     * List of read permissions being requested.
     */
    private static final List<String> READ_PERMISSIONS = Arrays.asList("email");

    /**
     * Activity code to flag an incoming activity result is due to a new
     * permissions request.
     */
    private static final int REAUTH_ACTIVITY_CODE = 100;

    /**
     * The bluetooth helper.
     */
    private BluetoothHelper bluetoothHelper;

    @SuppressWarnings("rawtypes")
    private AsyncTask currentRunningTask;

    /**
     * Callback called when excel export task is done.
     */
    private final IAsyncCallback<String> excelExportCallback = new IAsyncCallback<String>() {

        @Override
        public void execute(String filePath, Exception e) {

            // TODO Check exception
            onGameSetExportedToExcelFile(filePath);
        }
    };

    /**
     * "Yes / No" export excel by email.
     */
    private final DialogInterface.OnClickListener exportExcelByEmailDialogClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(final DialogInterface dialog, final int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                try {
                    Uri uri = Uri.fromFile(new File(tempExcelFilePath));

                    StringBuilder contentText = new StringBuilder();
                    contentText.append(getString(R.string.lblDbExportEmailContent));

                    Intent intent = new Intent(Intent.ACTION_SEND);
                    intent.setType("message/rfc822");
                    intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.lblDbExportEmailTitle));
                    intent.putExtra(Intent.EXTRA_TEXT, contentText.toString());
                    intent.putExtra(Intent.EXTRA_STREAM, uri);

                    startActivity(Intent.createChooser(intent, getString(R.string.lblDbExportAndroidIntentTitle)));
                } catch (Exception e) {
                    AuditHelper.auditError(ErrorTypes.exportExcelError, e, GameSetHistoryActivity.this);
                }
                break;
            case DialogInterface.BUTTON_NEGATIVE:
            default:
                break;
            }
        }
    };

    /**
     * Facebook session state change callback.
     */
    private final Session.StatusCallback facebookSessionStatusCallback = new Session.StatusCallback() {
        @Override
        public void call(Session session, SessionState state, Exception exception) {
            onSessionStateChange(session, state, exception);
        }
    };

    /**
     * Http client for communication with the cloud.
     */
    private DefaultHttpClient httpClient;

    /**
     * Indicates an on-going reauthorization request
     */
    private boolean pendingReauthRequest;

    /**
     * Callback used after post on facebook wall.
     */
    private final IAsyncCallback<Response> postToFacebookWallCallback = new IAsyncCallback<Response>() {

        @Override
        public void execute(Response facebookResponse, Exception e) {
            // TODO Check Exception
            GameSetHistoryActivity.this.onPostPublishGameSetOnFacebookWall(facebookResponse);
        }
    };

    /**
     * The progress dialog.
     */
    private ProgressDialog progressDialog;

    /**
     * The AsyncTask to receive a GameSet.
     */
    private ReceiveGameSetTask receiveGameSetTask;

    /**
     * Callback used to refresh the list.
     */
    private final IAsyncCallback<Object> refreshCallback = new IAsyncCallback<Object>() {

        @Override
        public void execute(Object isNull, Exception e) {
            // TODO Check if exception must not be handled
            GameSetHistoryActivity.this.refresh();
        }
    };

    /**
     * "Yes / No" remove all gamesets dialog box listener.
     */
    private final DialogInterface.OnClickListener removeAllGameSetsDialogClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(final DialogInterface dialog, final int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                RemoveAllGameSetsTask removeAllGameSetsTask = new RemoveAllGameSetsTask(GameSetHistoryActivity.this,
                        GameSetHistoryActivity.this.progressDialog);
                removeAllGameSetsTask.setCallback(refreshCallback);
                removeAllGameSetsTask.execute();
                break;

            case DialogInterface.BUTTON_NEGATIVE:
            default:
                break;
            }
        }
    };

    /**
     * The AsyncTask to send a GameSet.
     */
    private SendGameSetTask sendGameSetTask;

    /**
     * Temporary path for Excel path. Use with care, this is pretty much a
     * global variable (it's used between differents inner classes).
     */
    private String tempExcelFilePath;

    /**
     * Temporary GameSet. Use with care, this is pretty much a global variable
     * (it's used between differents inner classes).
     */
    private GameSet tempGameSet;

    /**
     * Facebook ui lifecyle manager.
     */
    private UiLifecycleHelper uiHelper;

    /**
     * Callback to execute when post has been posted to facebook.
     */
    private final IAsyncCallback<Object> upSyncCallback = new IAsyncCallback<Object>() {

        @Override
        public void execute(Object object, Exception e) {
            // TODO Check exception
            GameSetHistoryActivity.this.publishGameSetOnFacebook();
        }
    };

    /**
     * Traces creation event.
     */
    private void auditEvent() {
        AuditHelper.auditEvent(AuditHelper.EventTypes.displayGameSetHistoryPage);
    }

    /**
     * Handle facebook error.
     * 
     * @param error
     */
    private void handleFacebookError(final FacebookRequestError error) {
        DialogInterface.OnClickListener listener = null;
        String dialogBody = null;

        if (error == null) {
            dialogBody = getString(R.string.error_dialog_default_text);
        } else {

            dialogBody = error.toString();

            // Show the error and pass in the listener so action
            // can be taken, if necessary.
            new AlertDialog.Builder(this).setPositiveButton(R.string.error_dialog_button_text, listener)
                    .setTitle(R.string.error_dialog_title).setMessage(dialogBody).show();
        }
    }

    /**
     * Checks whether the current session is allowed to publish on facebook.
     * 
     * @return true if the session can publish, false otherwisee.
     */
    private boolean hasPublishPermission() {
        Session session = Session.getActiveSession();
        return session != null && session.getPermissions().containsAll(PUBLISH_PERMISSIONS);
    }

    /**
     * Checks whether the current session is allowed to read on facebook.
     * 
     * @return
     */
    private boolean hasReadPermission() {
        Session session = Session.getActiveSession();
        return session != null && session.getPermissions().containsAll(READ_PERMISSIONS);
    }

    /**
     * Indicates whether the bluetooth is activated on the device.
     * 
     * @return
     */
    private boolean isBluetoothActivated() {
        boolean isActivated = GameSetHistoryActivity.this.bluetoothHelper.isBluetoothEnabled();
        if (!isActivated) {
            Toast.makeText(GameSetHistoryActivity.this,
                    AppContext.getApplication().getResources().getString(R.string.msgActivateBluetooth),
                    Toast.LENGTH_SHORT).show();
        }
        return isActivated;
    }

    /**
     * Starts the whole Facebook post process.
     * 
     * @param session
     */
    private void launchPostProcess(final Session session) {

        LayoutInflater inflater = getLayoutInflater();
        View layout = inflater.inflate(R.layout.toast, (ViewGroup) findViewById(R.id.toast_layout_root));

        ImageView image = (ImageView) layout.findViewById(R.id.image);
        image.setImageResource(R.drawable.icon_facebook_released);
        TextView text = (TextView) layout.findViewById(R.id.text);
        text.setText("Publication en cours");

        Toast toast = new Toast(getApplicationContext());
        toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setView(layout);
        toast.show();

        Request request = Request.newMeRequest(session, new Request.GraphUserCallback() {

            @Override
            public void onCompleted(GraphUser user, Response response) {
                if (session == Session.getActiveSession()) {
                    if (user != null) {
                        int notificationId = FacebookHelper
                                .showNotificationStartProgress(GameSetHistoryActivity.this);
                        AppContext.getApplication().getNotificationIds().put(tempGameSet.getUuid(), notificationId);

                        AppContext.getApplication().setLoggedFacebookUser(user);
                        UpSyncGameSetTask task = new UpSyncGameSetTask(GameSetHistoryActivity.this, progressDialog);
                        task.setCallback(GameSetHistoryActivity.this.upSyncCallback);
                        task.execute(tempGameSet);
                        currentRunningTask = task;
                    }
                }
                if (response.getError() != null) {
                    // //progressDialog.dismiss();
                    // Session newSession = new
                    // Session(GameSetHistoryActivity.this);
                    // Session.setActiveSession(newSession);
                    // newSession.openForPublish(new
                    // Session.OpenRequest(GameSetHistoryActivity.this).setPermissions(Arrays.asList("publish_actions",
                    // "email")).setCallback(facebookSessionStatusCallback));
                }
            }
        });
        request.executeAsync();
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onActivityResult(int, int,
     * android.content.Intent)
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        this.uiHelper.onActivityResult(requestCode, resultCode, data);
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onBackPressed()
     */
    @Override
    public void onBackPressed() {
        // cancel send task if running
        try {
            if (this.sendGameSetTask != null) {
                this.sendGameSetTask.cancel(true);
            }
        } catch (Exception e) {
        }

        // cancel receive task if running
        try {
            if (this.receiveGameSetTask != null) {
                this.receiveGameSetTask.cancel(true);
            }
        } catch (Exception e) {
        }

        super.onBackPressed();
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        try {
            super.onCreate(savedInstanceState);

            // facebook lifecycle objects
            this.uiHelper = new UiLifecycleHelper(this, facebookSessionStatusCallback);
            this.uiHelper.onCreate(savedInstanceState);

            this.auditEvent();
            // initialize progress dialog
            this.progressDialog = new ProgressDialog(this);
            this.progressDialog.setCanceledOnTouchOutside(false);

            this.httpClient = new DefaultHttpClient();
            HttpParams httpParams = new BasicHttpParams();
            HttpProtocolParams.setContentCharset(httpParams, Charsets.UTF_8.toString());
            httpClient.setParams(httpParams);

            // initialize bluetooth
            this.bluetoothHelper = AppContext.getApplication().getBluetoothHelper();
            this.bluetoothHelper.setActivity(this);

            // set excuse as background image
            this.getListView().setCacheColorHint(0);
            this.getListView().setBackgroundResource(R.drawable.img_excuse);

            // set action bar properties
            this.setTitle();
            this.registerForContextMenu(this.getListView());

            // set internal properties
            this.tempExcelFilePath = null;
            this.tempGameSet = null;

            // wait for the dal to be initiated to refresh the game sets
            if (AppContext.getApplication().getLoadDalTask().getStatus() == AsyncTask.Status.RUNNING) {
                AppContext.getApplication().getLoadDalTask().showDialogOnActivity(this,
                        this.getResources().getString(R.string.msgGameSetsRetrieval));
                AppContext.getApplication().getLoadDalTask().setCallback(new IAsyncCallback<String>() {

                    @Override
                    public void execute(String result, Exception e) {

                        // TODO Check exception
                        if (result != null && result.toString().length() > 0) {
                            UIHelper.showSimpleRichTextDialog(GameSetHistoryActivity.this, result,
                                    "Erreur de chargement");
                        }

                        GameSetHistoryActivity.this.refresh();
                    }
                });
            }
            // refresh the game sets
            else {
                this.refresh();
            }

            Object currentRunningTask = getLastNonConfigurationInstance();
            if (currentRunningTask != null) {
                if (currentRunningTask instanceof UpSyncGameSetTask) {
                    UpSyncGameSetTask task = (UpSyncGameSetTask) currentRunningTask;
                    task.attach(this);
                } else if (currentRunningTask instanceof PostGameSetLinkOnFacebookWallTask) {
                    PostGameSetLinkOnFacebookWallTask task = (PostGameSetLinkOnFacebookWallTask) currentRunningTask;
                    task.attach(this);
                }
            }

            this.getListView().setOnItemLongClickListener(new OnItemLongClickListener() {

                @Override
                public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                    onListItemClick(pos);
                    return false;
                }
            });

            this.getListView().setOnItemClickListener(new OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                    onListItemClick(pos);
                }
            });
        } catch (Exception e) {
            AuditHelper.auditError(ErrorTypes.gameSetHistoryActivityError, e, this);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.actionbarsherlock.app.SherlockListActivity#onCreateOptionsMenu(android
     * .view.Menu)
     */
    @Override
    public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {

        SubMenu subMenuBlueTooth = menu.addSubMenu(this.getString(R.string.lblBluetoothItem));
        com.actionbarsherlock.view.MenuItem miBluetooth = subMenuBlueTooth.getItem();
        miBluetooth.setIcon(R.drawable.stat_sys_data_bluetooth);
        miBluetooth.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);

        com.actionbarsherlock.view.MenuItem miBlueToothDiscover = subMenuBlueTooth
                .add(R.string.lblBluetoothDiscover).setIcon(R.drawable.ic_menu_allfriends);
        com.actionbarsherlock.view.MenuItem miBlueToothGetDiscoverable = subMenuBlueTooth
                .add(R.string.lblBluetoothGetDiscoverable).setIcon(android.R.drawable.ic_menu_myplaces);
        com.actionbarsherlock.view.MenuItem miBlueToothReceive = subMenuBlueTooth.add(R.string.lblBluetoothReceive)
                .setIcon(R.drawable.ic_menu_download);
        com.actionbarsherlock.view.MenuItem miBlueToothHelp = subMenuBlueTooth.add(R.string.lblBluetoothHelp)
                .setIcon(android.R.drawable.ic_menu_info_details);

        miBlueToothDiscover.setOnMenuItemClickListener(new OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(com.actionbarsherlock.view.MenuItem item) {
                if (isBluetoothActivated()) {
                    GameSetHistoryActivity.this.bluetoothHelper.startDiscovery();
                    AuditHelper.auditEvent(AuditHelper.EventTypes.actionBluetoothDiscoverDevices);
                }
                return true;
            }
        });

        miBlueToothGetDiscoverable.setOnMenuItemClickListener(new OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(com.actionbarsherlock.view.MenuItem item) {
                if (isBluetoothActivated()) {
                    GameSetHistoryActivity.this.bluetoothHelper.setBluetoothDeviceDiscoverable();
                    AuditHelper.auditEvent(AuditHelper.EventTypes.actionBluetoothSetDiscoverable);
                }
                return true;
            }
        });

        miBlueToothReceive.setOnMenuItemClickListener(new OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(com.actionbarsherlock.view.MenuItem item) {
                if (isBluetoothActivated()) {
                    // retrieve game count
                    int gameSetCount;
                    try {
                        gameSetCount = AppContext.getApplication().getDalService().getGameSetCount();
                    } catch (DalException de) {
                        gameSetCount = 0;
                    }

                    // prevent user from downloading if game set count > 5 and
                    // limited version
                    if (AppContext.getApplication().isAppLimited() && gameSetCount >= 5) {
                        Toast.makeText(GameSetHistoryActivity.this,
                                AppContext.getApplication().getResources()
                                        .getString(R.string.msgLimitedVersionInformation),
                                Toast.LENGTH_SHORT).show();
                    }

                    // ok for download
                    else {
                        try {
                            GameSetHistoryActivity.this.receiveGameSetTask = new ReceiveGameSetTask(
                                    GameSetHistoryActivity.this, GameSetHistoryActivity.this.progressDialog,
                                    GameSetHistoryActivity.this.bluetoothHelper.getBluetoothAdapter());
                            GameSetHistoryActivity.this.receiveGameSetTask.setCallback(refreshCallback);
                            GameSetHistoryActivity.this.receiveGameSetTask.execute();
                            AuditHelper.auditEvent(AuditHelper.EventTypes.actionBluetoothReceiveGameSet);
                        } catch (IOException ioe) {
                            Log.v(AppContext.getApplication().getAppLogTag(),
                                    "TarotDroid Exception in " + this.getClass().toString(), ioe);
                            Toast.makeText(GameSetHistoryActivity.this, AppContext.getApplication().getResources()
                                    .getString(R.string.msgBluetoothError, ioe), Toast.LENGTH_SHORT).show();
                        }
                    }
                }
                return true;
            }
        });

        miBlueToothHelp.setOnMenuItemClickListener(new OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(com.actionbarsherlock.view.MenuItem item) {
                UIHelper.showSimpleRichTextDialog(GameSetHistoryActivity.this,
                        AppContext.getApplication().getResources().getText(R.string.msgHelpBluetooth).toString(),
                        AppContext.getApplication().getResources().getString(R.string.titleHelpBluetooth));
                return true;
            }
        });

        // TODO Improve Massive excel export
        // if (!AppContext.getApplication().isAppLimited()) {
        // com.actionbarsherlock.view.MenuItem miGlobalExport =
        // menu.add(this.getString(R.string.lblExcelExport)).setIcon(R.drawable.ic_excel);
        // miGlobalExport.setShowAsAction(com.actionbarsherlock.view.MenuItem.SHOW_AS_ACTION_NEVER);
        // //miGlobalExport.setIcon(R.drawable.ic_excel);
        //
        // miGlobalExport.setOnMenuItemClickListener(new
        // OnMenuItemClickListener() {
        // @Override
        // public boolean onMenuItemClick(com.actionbarsherlock.view.MenuItem
        // item) {
        // ExportToExcelTask task = new
        // ExportToExcelTask(GameSetHistoryActivity.this, progressDialog);
        // task.execute();
        // return true;
        // }
        // });
        // }

        com.actionbarsherlock.view.MenuItem miBin = menu.add(this.getString(R.string.lblInitDalItem));
        miBin.setShowAsAction(com.actionbarsherlock.view.MenuItem.SHOW_AS_ACTION_NEVER);
        miBin.setIcon(R.drawable.gd_action_bar_trashcan);

        miBin.setOnMenuItemClickListener(new OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(com.actionbarsherlock.view.MenuItem item) {
                AlertDialog.Builder builder = new AlertDialog.Builder(GameSetHistoryActivity.this);
                builder.setTitle(GameSetHistoryActivity.this.getString(R.string.titleReinitDalYesNo));
                builder.setMessage(
                        Html.fromHtml(GameSetHistoryActivity.this.getText(R.string.msgReinitDalYesNo).toString()));
                builder.setPositiveButton(GameSetHistoryActivity.this.getString(R.string.btnOk),
                        GameSetHistoryActivity.this.removeAllGameSetsDialogClickListener);
                builder.setNegativeButton(GameSetHistoryActivity.this.getString(R.string.btnCancel),
                        GameSetHistoryActivity.this.removeAllGameSetsDialogClickListener).show();
                builder.setIcon(android.R.drawable.ic_dialog_alert);
                return true;
            }
        });

        return true;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.actionbarsherlock.app.SherlockListActivity#onDestroy()
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.uiHelper.onDestroy();
        try {
            this.bluetoothHelper.cancelDiscovery();
        } catch (Exception e) {
        }
    }

    // /**
    // * Read session opened callback.
    // */
    // private Session.StatusCallback readSessionOpenedStatusCallback = new
    // Session.StatusCallback() {
    // @Override
    // public void call(Session session, SessionState state, Exception
    // exception) {
    // requestPublishPermissions(session);
    // }
    // };

    /**
     * Called when excel export task is done.
     * 
     * @param filePath
     */
    private void onGameSetExportedToExcelFile(String filePath) {
        // should never happen
        if (filePath == null) {
            UIHelper.showSimpleRichTextDialog(this, this.getString(R.string.msgDbExportFailed),
                    this.getString(R.string.titleDbExportFailed));
        }

        else {
            this.tempExcelFilePath = filePath;
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(this.getString(R.string.titleGameSetExportedToExcelFile));
            builder.setMessage(Html.fromHtml(this.getText(R.string.msgGameSetExportedToExcelFile).toString()));
            builder.setPositiveButton(this.getString(R.string.btnOk), this.exportExcelByEmailDialogClickListener);
            builder.setNegativeButton(this.getString(R.string.btnCancel),
                    this.exportExcelByEmailDialogClickListener);
            builder.setIcon(android.R.drawable.ic_dialog_alert);
            builder.show();
        }
    }

    /**
     * Manage click on GameSet.
     * 
     * @param pos
     */
    private void onListItemClick(final int pos) {
        final GameSet gameSet = (GameSet) getListAdapter().getItem(pos);

        final Item[] items = AppContext.getApplication().isAppLimited() ? limitedItems : allItems;

        ListAdapter adapter = new ArrayAdapter<Item>(this, android.R.layout.select_dialog_item, android.R.id.text1,
                items) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // User super class to create the View
                View v = super.getView(position, convertView, parent);
                TextView tv = (TextView) v.findViewById(android.R.id.text1);

                // Put the image on the TextView
                tv.setCompoundDrawablesWithIntrinsicBounds(items[position].icon, 0, 0, 0);

                // Add margin between image and text (support various screen
                // densities)
                int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
                tv.setCompoundDrawablePadding(dp5);

                return v;
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(String.format(this.getString(R.string.lblGameSetHistoryActivityMenuTitle),
                new SimpleDateFormat("dd/MM/yy").format(gameSet.getCreationTs())));

        builder.setAdapter(adapter, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int itemIndex) {

                Item item = items[itemIndex];

                if (item.itemType == Item.ItemTypes.publishOnFacebook) {

                    // check for active internet connexion first
                    // see post
                    // http://stackoverflow.com/questions/2789612/how-can-i-check-whether-an-android-device-is-connected-to-the-web
                    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(
                            Context.CONNECTIVITY_SERVICE);
                    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

                    if (networkInfo != null && networkInfo.isConnected()) {

                        if (gameSet.getGameCount() == 0) {
                            Toast.makeText(GameSetHistoryActivity.this,
                                    R.string.lblFacebookImpossibleToPublishGamesetWithNoGame, Toast.LENGTH_SHORT)
                                    .show();
                        }

                        else if (!AppContext.getApplication().getNotificationIds().isEmpty()) {
                            Toast.makeText(GameSetHistoryActivity.this, R.string.lblFacebookGamesetBeingPublished,
                                    Toast.LENGTH_SHORT).show();
                        }

                        else {
                            tempGameSet = gameSet;

                            // // TODO Improve in later version
                            // ShortenUrlTask shortenUrlTask = new
                            // ShortenUrlTask(FacebookHelper.buildGameSetUrl(tempGameSet));
                            // shortenUrlTask.setCallback(urlShortenedCallback);
                            // shortenUrlTask.execute();

                            startPostProcess();
                        }
                    } else {
                        Toast.makeText(GameSetHistoryActivity.this,
                                getString(R.string.titleInternetConnexionNecessary), Toast.LENGTH_LONG).show();
                    }
                } else if (item.itemType == Item.ItemTypes.publishOnTwitter) {
                    Toast.makeText(GameSetHistoryActivity.this, "TODO: Publish on twitter", Toast.LENGTH_LONG)
                            .show();

                    Intent intent = new Intent(GameSetHistoryActivity.this, TwitterConnectActivity.class);
                    startActivity(intent);
                } else if (item.itemType == Item.ItemTypes.remove) {
                    RemoveGameSetDialogClickListener removeGameSetDialogClickListener = new RemoveGameSetDialogClickListener(
                            gameSet);
                    AlertDialog.Builder builder = new AlertDialog.Builder(GameSetHistoryActivity.this);
                    builder.setTitle(GameSetHistoryActivity.this.getString(R.string.titleRemoveGameSetYesNo));
                    builder.setMessage(Html.fromHtml(
                            GameSetHistoryActivity.this.getText(R.string.msgRemoveGameSetYesNo).toString()));
                    builder.setPositiveButton(GameSetHistoryActivity.this.getString(R.string.btnOk),
                            removeGameSetDialogClickListener);
                    builder.setNegativeButton(GameSetHistoryActivity.this.getString(R.string.btnCancel),
                            removeGameSetDialogClickListener).show();
                    builder.setIcon(android.R.drawable.ic_dialog_alert);
                } else if (item.itemType == Item.ItemTypes.transferOverBluetooth) {
                    if (!GameSetHistoryActivity.this.bluetoothHelper.isBluetoothEnabled()) {
                        Toast.makeText(GameSetHistoryActivity.this,
                                GameSetHistoryActivity.this.getString(R.string.msgActivateBluetooth),
                                Toast.LENGTH_LONG).show();
                    }

                    try {
                        // make sure at least one device was discovered
                        if (GameSetHistoryActivity.this.bluetoothHelper.getBluetoothDeviceCount() == 0) {
                            Toast.makeText(GameSetHistoryActivity.this,
                                    GameSetHistoryActivity.this.getString(R.string.msgRunDiscoverDevicesFirst),
                                    Toast.LENGTH_LONG).show();
                        }

                        // display devices and download
                        final String[] items = GameSetHistoryActivity.this.bluetoothHelper
                                .getBluetoothDeviceNames();

                        AlertDialog.Builder builder = new AlertDialog.Builder(GameSetHistoryActivity.this);
                        builder.setTitle(GameSetHistoryActivity.this.getString(R.string.lblSelectBluetoothDevice));
                        builder.setItems(items, new BluetoothDeviceClickListener(gameSet, items));
                        AlertDialog alert = builder.create();
                        alert.show();
                    } catch (Exception e) {
                        AuditHelper.auditError(ErrorTypes.gameSetHistoryActivityError, e,
                                GameSetHistoryActivity.this);
                    }
                } else if (item.itemType == Item.ItemTypes.exportToExcel) {
                    try {
                        if (!AppContext.getApplication().isAppLimited()) {

                            ExportToExcelTask task = new ExportToExcelTask(GameSetHistoryActivity.this,
                                    progressDialog);
                            task.setCallback(excelExportCallback);
                            task.execute(gameSet);
                        }
                    } catch (Exception e) {
                        Toast.makeText(
                                GameSetHistoryActivity.this, AppContext.getApplication().getResources()
                                        .getText(R.string.msgGameSetExportError).toString() + e.getMessage(),
                                Toast.LENGTH_LONG).show();
                        AuditHelper.auditError(ErrorTypes.excelFileStorage, e);
                    }
                } else if (item.itemType == Item.ItemTypes.edit) {
                    // SharedPreferences preferences =
                    // PreferenceManager.getDefaultSharedPreferences(GameSetHistoryActivity.this);

                    // set selected gameset as session gameset
                    // AppContext.getApplication().getBizService().setGameSet(gameSet);

                    // // Get non DAL stored parameters property from shared
                    // preferences
                    // UIHelper.fillNonComputationPreferences(gameSet.getGameSetParameters(),
                    // preferences);

                    // start tab gameset activity
                    Intent intent = new Intent(GameSetHistoryActivity.this, TabGameSetActivity.class);
                    intent.putExtra(ActivityParams.PARAM_GAMESET_ID, gameSet.getId());
                    GameSetHistoryActivity.this.startActivityForResult(intent, RequestCodes.DISPLAY_WITH_FACEBOOK);
                }
            }
        });
        AlertDialog alert = builder.create();
        alert.show();

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.actionbarsherlock.app.SherlockListActivity#onPause()
     */
    @Override
    protected void onPause() {
        super.onPause();
        this.uiHelper.onPause();
    }

    /**
     * Method called asynchronously after publishGameSetOnFacebookWall().
     * 
     * @param facebookResponse
     */
    private void onPostPublishGameSetOnFacebookWall(final Response facebookResponse) {
        PostResponse postResponse = facebookResponse.getGraphObjectAs(PostResponse.class);

        int notificationId = AppContext.getApplication().getNotificationIds().get(tempGameSet.getUuid());
        AppContext.getApplication().getNotificationIds().remove(tempGameSet.getUuid());
        if (postResponse != null && postResponse.getId() != null) {
            FacebookHelper.showNotificationStopProgressSuccess(this, FacebookHelper.buildGameSetUrl(tempGameSet),
                    notificationId);
            try {
                tempGameSet.setFacebookPostTs(new Date());
                AppContext.getApplication().getDalService().updateGameSetAfterSync(tempGameSet);
                refresh();
            } catch (DalException e) {
                e.printStackTrace();
                AuditHelper.auditError(ErrorTypes.updateGameSetError, e, this);
            }
            // this.publishGameSetOnFacebookApp();
        } else {
            FacebookHelper.showNotificationStopProgressFailure(this, notificationId);
            this.handleFacebookError(facebookResponse.getError());
        }
    }

    // /**
    // * Published session opened callback.
    // */
    // private Session.StatusCallback publishSessionOpenedCallback = new
    // Session.StatusCallback() {
    // @Override
    // public void call(Session session, SessionState state, Exception
    // exception) {
    // launchPostProcess(session);
    // }
    // };

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.actionbarsherlock.app.SherlockListActivity#onRestoreInstanceState
     * (android.os.Bundle)
     */
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        this.pendingReauthRequest = savedInstanceState.getBoolean(PENDING_REAUTH_KEY, false);
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onResume()
     */
    @Override
    protected void onResume() {
        super.onResume();
        this.uiHelper.onResume();
        if (AppContext.getApplication().getLoadDalTask().getStatus() == AsyncTask.Status.FINISHED) {
            this.refresh();
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onRetainNonConfigurationInstance()
     */
    @Override
    public Object onRetainNonConfigurationInstance() {
        Object toReturn = null;
        if (currentRunningTask == null) {
            toReturn = null;
        } else if (currentRunningTask instanceof UpSyncGameSetTask) {
            UpSyncGameSetTask task = (UpSyncGameSetTask) currentRunningTask;
            task.detach();
            toReturn = task;
        } else if (currentRunningTask instanceof PostGameSetLinkOnFacebookWallTask) {
            PostGameSetLinkOnFacebookWallTask task = (PostGameSetLinkOnFacebookWallTask) currentRunningTask;
            task.detach();
            toReturn = task;
        }

        return toReturn;
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(PENDING_REAUTH_KEY, this.pendingReauthRequest);
        this.uiHelper.onSaveInstanceState(outState);
    }

    // /**
    // * Post game set to Facebook Wall.
    // */
    // private void publishGameSetOnFacebookApp() {
    // PostGameSetOnFacebookAppTask postGameSetOnFacebookAppTask = new
    // PostGameSetOnFacebookAppTask(this, this.progressDialog, tempGameSet);
    // postGameSetOnFacebookAppTask.setCallback(this.postToFacebookAppCallback);
    // postGameSetOnFacebookAppTask.execute();
    // }

    // /**
    // * Method called asynchronously after publishGameSetOnFacebookApp().
    // * @param facebookResponse
    // */
    // private void onPostPublishGameSetOnFacebookApp(final Response
    // facebookResponse) {
    // PostResponse postResponse =
    // facebookResponse.getGraphObjectAs(PostResponse.class);
    //
    // if (postResponse == null || postResponse.getId() == null) {
    // }
    // }

    /**
     * Called when session changed.
     * 
     * @param session
     * @param state
     * @param exception
     */
    private void onSessionStateChange(Session session, SessionState state, Exception exception) {
        // ask for publish permissions
        if (tempGameSet != null && session.getState() == SessionState.OPENED && !hasPublishPermission()) {
            this.requestPublishPermissions(session);
        }

        // publish
        else if (this.tempGameSet != null && session.getState() == SessionState.OPENED_TOKEN_UPDATED
                && hasReadPermission() && hasPublishPermission()) {
            this.launchPostProcess(session);
        }

        // some problem, restart whole publication process
        else if (this.tempGameSet != null && session.isClosed()) {
            session.closeAndClearTokenInformation();
            Toast.makeText(this, "Vous devez relancer la publication Facebook...", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * Opens a read session before opening a publish session.
     * 
     * @param callback
     */
    private void openFacebookSessionForRead(Session session) {
        if (session != null) {
            // session.openForRead(new
            // Session.OpenRequest(this).setPermissions(READ_PERMISSIONS).setCallback(readSessionOpenedStatusCallback));
            session.openForRead(new Session.OpenRequest(this).setPermissions(READ_PERMISSIONS));
        }
    }

    /**
     * Publish the game set on Facebook.
     */
    private void publishGameSetOnFacebook() {
        Session session = Session.getActiveSession();
        this.pendingReauthRequest = false;
        if (session != null) {
            if (this.hasPublishPermission()) {
                this.publishGameSetOnFacebookWall();
            } else {
                this.pendingReauthRequest = true;
                this.requestPublishPermissions(session);
            }
        }
    }

    /**
     * Post game set to Facebook Wall.
     */
    private void publishGameSetOnFacebookWall() {
        PostGameSetLinkOnFacebookWallTask postGameSetLinkOnFacebookWallTask = new PostGameSetLinkOnFacebookWallTask(
                this, this.progressDialog, tempGameSet, null);
        postGameSetLinkOnFacebookWallTask.setCallback(this.postToFacebookWallCallback);
        postGameSetLinkOnFacebookWallTask.execute();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.nla.tarotdroid.ui.IRefreshableGameSetContainer#refresh()
     */
    // @Override
    public void refresh() {
        List<GameSet> gameSets = AppContext.getApplication().getDalService().getAllGameSets();
        Collections.sort(gameSets, gameSetCreationDateDescendingComparator);
        this.setListAdapter(new GameSetAdapter(this, gameSets));
        this.setTitle();
    }

    /**
     * Initiates a new request for permissions.
     * 
     * @param session
     */
    private void requestPublishPermissions(Session session) {
        if (!this.hasPublishPermission()) {

            // request publish permissions if session was just opened
            if (session.getState() == SessionState.OPENED) {

                // HACK because of bug explained here
                // http://stackoverflow.com/questions/14037010/statuscallback-not-called-after-requestnewreadpermissions-then-requestnewpublish
                // Session.openActiveSessionFromCache(this);
                // END HACK

                // Session.NewPermissionsRequest newPermissionsRequest = new
                // Session.NewPermissionsRequest(this,
                // PUBLISH_PERMISSIONS).setRequestCode(REAUTH_ACTIVITY_CODE).setCallback(publishSessionOpenedCallback);
                Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this,
                        PUBLISH_PERMISSIONS).setRequestCode(REAUTH_ACTIVITY_CODE);
                session.requestNewPublishPermissions(newPermissionsRequest);
            }

            // do nothing if session was already updated
            else if (session.getState() == SessionState.OPENED_TOKEN_UPDATED) {
            }
        }
    }

    /**
     * Runs a task to transfer a game set.
     */
    private void sendGameSetOverBluetooth(final GameSet gameSet, final BluetoothDevice bluetoothDevice) {
        try {
            AuditHelper.auditEvent(EventTypes.actionBluetoothSendGameSet);
            this.sendGameSetTask = new SendGameSetTask(this, this.progressDialog, gameSet, bluetoothDevice,
                    this.bluetoothHelper.getBluetoothAdapter());
            this.sendGameSetTask.setCallback(refreshCallback);
            this.sendGameSetTask.execute();
        } catch (IOException ioe) {
            Log.v(AppContext.getApplication().getAppLogTag(),
                    "TarotDroid Exception in " + this.getClass().toString(), ioe);
            Toast.makeText(GameSetHistoryActivity.this,
                    this.getResources().getString(R.string.msgBluetoothError, ioe), Toast.LENGTH_LONG).show();
        }
    }

    /**
     * Sets adhoc title.
     */
    private void setTitle() {
        if (AppContext.getApplication().getDalService() == null
                || AppContext.getApplication().getDalService().getAllGameSets().size() == 0) {
            this.setTitle(this.getResources().getString(R.string.lblGameSetHistoryActivityTitleNone));
        } else if (AppContext.getApplication().getDalService().getAllGameSets().size() == 1) {
            this.setTitle(this.getResources().getString(R.string.lblGameSetHistoryActivityTitleSingle));
        } else {
            this.setTitle(this.getResources().getString(R.string.lblGameSetHistoryActivityTitlePlural,
                    AppContext.getApplication().getDalService().getAllGameSets().size()));
        }

    }

    /**
     * Attempts to start the publish process.
     */
    private void startPostProcess() {
        Session session = Session.getActiveSession();
        if (session == null || session.isClosed()) {
            session = new Session(this);
            Session.setActiveSession(session);
        }

        if (!hasReadPermission()) {
            openFacebookSessionForRead(session);
            return;
        }

        if (!hasPublishPermission()) {
            requestPublishPermissions(session);
            return;
        }

        this.launchPostProcess(session);
    }
}