nl.atcomputing.spacetravelagency.activities.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for nl.atcomputing.spacetravelagency.activities.MainActivity.java

Source

/**
 * 
 * Copyright 2015 AT Computing BV
 *
 * This file is part of Space Travel Agency.
 *
 * Space Travel Agency 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.
 *
 * Space Travel Agency 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 Space Travel Agency.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package nl.atcomputing.spacetravelagency.activities;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import nl.atcomputing.spacetravelagency.R;
import nl.atcomputing.spacetravelagency.StateSingleton;
import nl.atcomputing.spacetravelagency.adapters.DestinationsAdapter;
import nl.atcomputing.spacetravelagency.adapters.DestinationsAdapter.DestinationsAdapterListener;
import nl.atcomputing.spacetravelagency.app.SoundSherlockFragmentActivity;
import nl.atcomputing.spacetravelagency.database.Database;
import nl.atcomputing.spacetravelagency.fragments.CheckoutFragment;
import nl.atcomputing.spacetravelagency.fragments.DestinationsFragment;
import nl.atcomputing.spacetravelagency.fragments.DestinationsFragment.DestinationsFragmentInterface;
import nl.atcomputing.spacetravelagency.fragments.PlanetInfoFragment;
import nl.atcomputing.spacetravelagency.fragments.PlanetInfoFragment.OnScrollableTextViewFragmentListener;
import nl.atcomputing.spacetravelagency.order.DepartureInfoService;
import nl.atcomputing.spacetravelagency.order.HttpCommunicator;
import nl.atcomputing.spacetravelagency.utils.Preferences;
import nl.atcomputing.spacetravelagency.utils.RotateImage;
import nl.atcomputing.spacetravelagency.utils.Sounds;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.ActionBar.TabListener;

public class MainActivity extends SoundSherlockFragmentActivity
        implements OnClickListener, DestinationsFragmentInterface, DestinationsAdapterListener, TabListener,
        SensorEventListener, OnScrollableTextViewFragmentListener {

    private final String BUNDLE_KEY_SELECTEDTAB = "BUNDLE_KEY_SELECTEDTAB";
    private final String BUNDLE_KEY_PLANETINFO = "BUNDLE_KEY_PLANETINFO";
    private final String TAG_PORTRAIT = "activity_main_port";
    private final String TAG_LANDSCAPE = "activity_main_land";

    private String layoutTag = "";

    private DestinationsAdapter sunPlanetsAdapter;
    private DestinationsAdapter siriusPlanetsAdapter;
    private String[] planetInfos;
    private String planetInfo;

    private String STAR_SYSTEM_SUN = "sun";
    private String STAR_SYSTEM_SIRIUS = "sirius";
    private String selectedTabName;

    private SensorManager sensorManager;
    private Sensor sensor;

    private Bitmap backgroundBitmapImage;
    private ImageView backgroundImageView;

    private BroadcastReceiver broadcastReceiver;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setupDatastructures();

        if (savedInstanceState != null) {
            this.planetInfo = savedInstanceState.getString(BUNDLE_KEY_PLANETINFO);
        }

        this.layoutTag = (String) findViewById(R.id.main_layout).getTag();
        if (this.layoutTag == null) {
            this.layoutTag = "";
        }
        setupFragments();

        addTabs();
        if (savedInstanceState != null) {
            this.selectedTabName = savedInstanceState.getString(BUNDLE_KEY_SELECTEDTAB);
            selectTab(this.selectedTabName);
        }

        DepartureInfoService.cancelDepartureInfoServiceAlarm(this);
        DepartureInfoService.setupDepartureInfoServiceAlarm(this);

        Button b = (Button) findViewById(R.id.button);
        b.setOnClickListener(this);

        this.sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        this.sensor = this.sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);

        if (this.layoutTag.contentEquals(TAG_PORTRAIT)) {
            /**
             * In portrait mode we show planet info if state is showing planet info
             * or checkout if state is checking out.
             * We assume that user rotated device to read the information fullscreen
             */
            if (StateSingleton.getInstance().isShowingPlanetInfo()) {
                showPlanetInfo();
            } else if (StateSingleton.getInstance().isCheckingOut()) {
                showCheckout();
            }
        } else {
            //In landscape mode we always show destinations list
            //in onResume we determine what to show next to the destinations list
            showDestinations();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (Preferences.animateBackground()) {
            this.backgroundImageView = (ImageView) findViewById(R.id.background_image);
            this.backgroundBitmapImage = BitmapFactory.decodeResource(getResources(), R.drawable.milky_way);
            this.sensorManager.registerListener(this, this.sensor, SensorManager.SENSOR_DELAY_NORMAL);
        }

        StateSingleton state = StateSingleton.getInstance();
        Log.d("MainActivity", "onResume: state=" + state);
        if (this.layoutTag.contentEquals(TAG_LANDSCAPE)) {
            if (state.isCheckingOut() || state.isPlacingOrder()) {
                showCheckout();
            } else if (state.isShowingPlanetInfo()) {
                showPlanetInfo();
            } else {
                state.setSelectingDestinations();
            }
        }

        this.broadcastReceiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                updateButton();
            }
        };
        registerReceiver(this.broadcastReceiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));

        updateButton();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (this.backgroundBitmapImage != null) {
            this.backgroundBitmapImage.recycle();
        }
        this.sensorManager.unregisterListener(this);

        unregisterReceiver(this.broadcastReceiver);
    }

    /**
     * We need to override onBackPressed to make sure
     * state is set to initial state when quitting the
     * App. When returning from checkout to the main activity
     * state is remembered (i.e. CHECKOUT). When user pressed
     * back again to quit the App the StateSingleton is retained.
     * This results in the App starting in Checkout mode when
     * user restarts the App from the launcher
     */
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        StateSingleton.getInstance().setSelectingDestinations();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putString(BUNDLE_KEY_SELECTEDTAB, this.selectedTabName);
        outState.putString(BUNDLE_KEY_PLANETINFO, this.planetInfo);
    }

    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button:
            if (layoutTag.contentEquals(TAG_LANDSCAPE)) {
                if (StateSingleton.getInstance().isCheckingOut()) {
                    StateSingleton.getInstance().setPlacingOrder();
                    showPlaceOrder();
                } else {
                    showCheckout();
                    StateSingleton.getInstance().setCheckingOut();
                    updateButton();
                }
            } else {
                showCheckout();
            }
            break;
        }
    }

    @Override
    public void onDestinationClicked(int pos) {
        StateSingleton.getInstance().setShowingPlanetInfo();
        this.planetInfo = this.planetInfos[pos];
        showPlanetInfo();
        updateButton();
    }

    @Override
    public void onCheckBoxStateChanged(boolean isChecked, int planetId) {
        StateSingleton.getInstance().setSelectingDestinations();

        int[] prices;
        int[] distances;
        String[] names;
        Database db;

        if (this.selectedTabName.contains(STAR_SYSTEM_SUN)) {
            db = new Database(this, STAR_SYSTEM_SUN);
            prices = getResources().getIntArray(R.array.sun_planets_price);
            names = getResources().getStringArray(R.array.sun_planets_names);
            distances = getResources().getIntArray(R.array.sun_planets_distance_from_center);
        } else {
            db = new Database(this, STAR_SYSTEM_SIRIUS);
            prices = getResources().getIntArray(R.array.sirius_planets_price);
            names = getResources().getStringArray(R.array.sirius_planets_names);
            distances = getResources().getIntArray(R.array.sirius_planets_distance_from_center);
        }

        db.open();
        if (isChecked) {
            db.addDestination(planetId, names[planetId], prices[planetId], distances[planetId]);
        } else {
            db.removeDestination(planetId);
        }
        db.close();

        //Any previous checkout is invalid now
        StateSingleton.getInstance().setTravellingOrder(null);
        StateSingleton.getInstance().setOrder(null);
        StateSingleton.getInstance().setInvitedFriend(null);
        StateSingleton.getInstance().setCalculateTravellingOrderTask(null);
        CheckoutFragment.remove(getSupportFragmentManager());

        updateButton();
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        if (this.selectedTabName != ((String) tab.getTag())) {
            this.selectedTabName = (String) tab.getTag();
            //         this.planetInfo = ""; // clear planet info if different galaxy is selected

            super.sounds.play(Sounds.Type.ITEMPRESS);
        }
        showDestinations();
        updateButton();
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        //      onTabSelected(tab, ft);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (this.backgroundImageView != null) {
            Bitmap bmRotated = RotateImage.rotate(this.backgroundBitmapImage, -event.values[0], event.values[1]);
            this.backgroundImageView.setImageBitmap(bmRotated);
        }
    }

    private DestinationsAdapter createAdapter(String starSystem, String[] planetNames, TypedArray planetIcons) {
        ArrayList<Map<String, Object>> planetMap = new ArrayList<Map<String, Object>>();

        for (int i = 0; i < planetNames.length; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("planetName", planetNames[i]);
            map.put("planetImage", Integer.valueOf(planetIcons.getResourceId(i, 0)));
            map.put("planetId", i);
            planetMap.add(map);
        }

        String[] fromMapKeys = new String[] { "planetImage", "planetName" };
        int[] toTargetResourceIds = new int[] { R.id.destinations_listview_item_planet_image,
                R.id.destinations_listview_item_planet_name };

        Database db = new Database(this, starSystem);
        return new DestinationsAdapter(this, this, db, planetMap, R.layout.destinations_listview_item, fromMapKeys,
                toTargetResourceIds);
    }

    private void setupFragments() {
        StateSingleton state = StateSingleton.getInstance();

        if (layoutTag.equals(TAG_LANDSCAPE)) {
            if (state.isCheckingOut()) {
                showCheckout();
            } else if (state.isShowingPlanetInfo()) {
                showPlanetInfo();
            }
        }
    }

    private void selectTab(String tabName) {
        ActionBar actionBar = getSupportActionBar();
        int amountOfTabs = actionBar.getTabCount();
        for (int i = 0; i < amountOfTabs; i++) {
            Tab tab = actionBar.getTabAt(i);
            if (((String) tab.getTag()).contains(tabName)) {
                tab.select();
                break;
            }
        }
    }

    private void addTabs() {
        ActionBar actionBar = getSupportActionBar();
        if (actionBar.getTabCount() > 0) { // tabs already available no need to add them again
            return;
        }

        this.selectedTabName = STAR_SYSTEM_SUN;

        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        Tab sunTab = actionBar.newTab();
        sunTab.setText(R.string.Sun);
        sunTab.setTabListener(this);
        sunTab.setTag(STAR_SYSTEM_SUN);
        actionBar.addTab(sunTab);

        Tab siriusTab = actionBar.newTab();
        siriusTab.setText(R.string.Sirius);
        siriusTab.setTabListener(this);
        siriusTab.setTag(STAR_SYSTEM_SIRIUS);
        actionBar.addTab(siriusTab);
    }

    private void setupDatastructures() {
        String[] planetNames = getResources().getStringArray(R.array.sun_planets_names);
        TypedArray planetIcons = getResources().obtainTypedArray(R.array.sun_planets_icons);
        this.sunPlanetsAdapter = createAdapter(this.STAR_SYSTEM_SUN, planetNames, planetIcons);

        planetNames = getResources().getStringArray(R.array.sirius_planets_names);
        planetIcons = getResources().obtainTypedArray(R.array.sirius_planets_icons);
        this.siriusPlanetsAdapter = createAdapter(this.STAR_SYSTEM_SIRIUS, planetNames, planetIcons);
        planetIcons.recycle();

        this.planetInfos = getResources().getStringArray(R.array.sun_planets_info);
    }

    private void updateButton() {
        Button button = (Button) findViewById(R.id.button);
        int stringResourceId = R.string.checkout;
        int amountChecked = this.sunPlanetsAdapter.getAmountOfCheckboxesSelected()
                + this.siriusPlanetsAdapter.getAmountOfCheckboxesSelected();

        Log.d("MainActivity", "updateButton: StateSingleton=" + StateSingleton.getInstance());

        StateSingleton state = StateSingleton.getInstance();
        if (this.layoutTag.contentEquals(TAG_LANDSCAPE)) {
            if (state.isCheckingOut() || state.isPlacingOrder()) {
                if (HttpCommunicator.isOnline(this)) {
                    stringResourceId = R.string.book_journey;
                    button.setEnabled(true);
                } else {
                    stringResourceId = R.string.enable_internet_to_book_journey;
                    button.setEnabled(false);
                }
            } else {
                if (amountChecked > 0) {
                    button.setEnabled(true);
                } else {
                    stringResourceId = R.string.please_select_your_destination_s_;
                    button.setEnabled(false);
                }
            }
        } else {
            if (amountChecked > 0) {
                button.setEnabled(true);
            } else {
                stringResourceId = R.string.please_select_your_destination_s_;
                button.setEnabled(false);
            }
        }

        button.setText(stringResourceId);
    }

    /**
     * Creates and attaches the fragment to display planet information
     * @param info text to display or null to show default text 
     */
    private void showPlanetInfo() {
        PlanetInfoFragment scrollableTextViewFragment = new PlanetInfoFragment();

        Bundle bundle = new Bundle();
        bundle.putString(PlanetInfoFragment.ARG_KEY_TEXT, this.planetInfo);
        scrollableTextViewFragment.setArguments(bundle);
        scrollableTextViewFragment.setListener(this);

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

        if (layoutTag.equals(TAG_PORTRAIT)) {
            Intent intent = new Intent(this, PlanetInfoActivity.class);
            intent.putExtra(PlanetInfoActivity.BUNDLE_KEY_PLANETINFO, this.planetInfo);
            startActivity(intent);
        } else {
            fragmentTransaction.replace(R.id.framelayout_fragment_planet_info, scrollableTextViewFragment);
            fragmentTransaction.commit();
        }
    }

    /**
     * Creates and attaches the fragment to display the list of destinations
     * @param tab that has been selected
     * @param ft used to replace the current fragment
     */
    private void showDestinations() {
        DestinationsAdapter adapter;

        if (this.selectedTabName.contentEquals(STAR_SYSTEM_SUN)) {
            adapter = this.sunPlanetsAdapter;
            this.planetInfos = getResources().getStringArray(R.array.sun_planets_info);
        } else {
            adapter = this.siriusPlanetsAdapter;
            this.planetInfos = getResources().getStringArray(R.array.sirius_planets_info);
        }

        DestinationsFragment destinationsFragment = new DestinationsFragment();

        destinationsFragment.setAdapter(adapter);

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        if (layoutTag.equals(TAG_PORTRAIT)) {
            fragmentTransaction.replace(R.id.framelayout_fragment_container, destinationsFragment);
        } else {
            fragmentTransaction.replace(R.id.framelayout_fragment_destinations, destinationsFragment);
        }
        fragmentTransaction.commit();
    }

    private void showCheckout() {
        if (layoutTag.equals(TAG_PORTRAIT)) {
            Intent intent = new Intent(this, CheckoutActivity.class);
            startActivity(intent);
        } else {
            CheckoutFragment.replace(R.id.framelayout_fragment_planet_info, getSupportFragmentManager());
        }

    }

    private void showPlaceOrder() {
        Intent intent = new Intent(this, PlaceOrderActivity.class);
        startActivity(intent);
    }

    @Override
    public void onTextViewClick() {
        Intent intent = new Intent(this, PlanetInfoActivity.class);
        intent.putExtra(PlanetInfoActivity.BUNDLE_KEY_PLANETINFO, this.planetInfo);
        startActivity(intent);
    }
}