Newer
Older
mountainnavigation / app / src / main / java / de / apps4ics / mountainnavigation / MainActivity.java
package de.apps4ics.mountainnavigation;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.provider.Settings;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.GravityCompat;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.DrawerLayout;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import com.survivingwithandroid.weather.lib.WeatherClient;
import com.survivingwithandroid.weather.lib.WeatherConfig;
import com.survivingwithandroid.weather.lib.exception.WeatherLibException;
import com.survivingwithandroid.weather.lib.exception.WeatherProviderInstantiationException;
import com.survivingwithandroid.weather.lib.model.CurrentWeather;
import com.survivingwithandroid.weather.lib.provider.openweathermap.OpenweathermapProviderType;
import com.survivingwithandroid.weather.lib.request.WeatherRequest;

import org.osmdroid.api.IMapController;
import org.osmdroid.bonuspack.overlays.Marker;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements LocationListener {

    public static final String TAG = "MountainNavigation";
    /**
     * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
     */

    /**
     * Used to store the last screen title. For use in {@link #restoreActionBar()}.
     */
    private CharSequence mTitle;
    private CharSequence mDrawerTitle;
    private static final int GPS_MIN_TIME = 5000;
    private static final int GPS_MIN_DIST = 5;

    private Resources res;
    private FloatingActionButton fab;

    private WeatherClient weatherClient;

    private DatabaseHandler dbHandler;

    private MapView mapView;
    private IMapController mapController;
    private int ZOOM_LEVEL;

    private ActionBarDrawerToggle drawerToggle;
    private String[] fountainSizes;
    private String[] entries;
    private Integer[] entryImgs;
    private Integer[] fountainImgs;
    private DrawerLayout drawerLayout;
    private ListView listView;

    private List<Poi> poiMarkers;

    private String provider;
    private Location mLocation;
    private LocationManager locationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        res = getResources();

        FrameLayout frameLayout = (FrameLayout) findViewById(R.id.container);

        dbHandler = new DatabaseHandler(this);

        ZOOM_LEVEL = 18;
        mapView = new MapView(getApplicationContext(), 256);
        mapView.setTileSource(TileSourceFactory.MAPNIK);
        mapView.setBuiltInZoomControls(true);
        mapView.setMultiTouchControls(true);
        mapController = mapView.getController();
        mapController.setZoom(ZOOM_LEVEL);
        mapController.setCenter(new GeoPoint(37.9777, 23.7277));

        poiMarkers = new ArrayList<>();

        frameLayout.addView(mapView);

        mTitle = mDrawerTitle = getTitle();

        initGps();

        fountainSizes = getResources().getStringArray(R.array.fountain_size_dialog_options);
        fountainImgs = new Integer[]{
                R.drawable.fountain_size_small,
                R.drawable.fountain_size_medium,
                R.drawable.fountain_size_big,
        };
        entries = getResources().getStringArray(R.array.toggleEntries);
        entryImgs  = new Integer[]{
                R.drawable.water,
                R.drawable.path,
                R.drawable.break_point,
                R.drawable.trash,
                R.drawable.image_upload,
                R.drawable.cell_reception,
                R.drawable.wifi,
                R.drawable.lift
        };

        WeatherClient.ClientBuilder weatherBuilder = new WeatherClient.ClientBuilder();
        WeatherConfig weatherConfig = new WeatherConfig();
        weatherConfig.unitSystem = WeatherConfig.UNIT_SYSTEM.M;

        weatherClient = null;
        try {
            weatherClient = weatherBuilder.attach(getApplicationContext())
                    .provider(new OpenweathermapProviderType())
                    .httpClient(com.survivingwithandroid.weather.lib.client.okhttp.WeatherDefaultClient.class)
                    .config(weatherConfig)
                    .build();
        } catch (WeatherProviderInstantiationException e) {
            e.printStackTrace();
        }

        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mLocation == null){
                    InformDialog informDialog = new InformDialog(getString(R.string.inform_title), getString(R.string.inform_gps_pos_not_found));
                    informDialog.show(getFragmentManager(), "Inform Dialog");
                    return;
                }
                AddPoiDialog addPoiDialog = new AddPoiDialog();
                addPoiDialog.show(getFragmentManager(), "Add POI Dialog");
            }
        });
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        listView = (ListView) findViewById(R.id.navigation_drawer);

        drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

//        listView.setItemsCanFocus(false);
        ImageListAdapter adapter = new ImageListAdapter(MainActivity.this, entries, entryImgs);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                TableLayout layout = (TableLayout) view;
                toggleDrawerItems(layout, position);
            }
        });

        drawerLayout.setDrawerListener(drawerToggle);
    }

    private void toggleDrawerItems(TableLayout layout, int position){
        TableRow tr = (TableRow) layout.getChildAt(0); //TODO is tablerow?
        TextView tv = null;
        ImageView iv = null;
        for(int i=0; i<tr.getChildCount(); ++i){
            View v = tr.getChildAt(i);
            try {
                tv = (TextView) v;
            } catch(ClassCastException cce){
                //Log.e(TAG, "Could not cast " + v.getClass().toString() + " to TextView!");
            }
            try {
                iv = (ImageView) v;
            } catch(ClassCastException cce){
                //Log.e(TAG, "Could not cast " + v.getClass().toString() + " to ImageView!");
            }
        }
        if(tv == null || iv == null) Log.e(TAG, "Neither TextView nor ImageView can be null!");
        int type = getType(position);
        if(iv.getTag() == null || iv.getTag() == "disabled"){
            iv.setColorFilter(null);
            iv.setTag("");
            tv.setTypeface(null, Typeface.BOLD);
            Toaster("You enabled " + entries[position]);
            List<Poi> tempPoiList = dbHandler.getPoiByType(type);
            for(int i=0; i<tempPoiList.size(); ++i){
                Poi poi = tempPoiList.get(i);
                poiMarkers.add(poi);
                GeoPoint gp = new GeoPoint(poi.getLat(), poi.getLon());

                Marker positionMarker = new Marker(mapView);
                positionMarker.setPosition(gp);
                positionMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
                positionMarker.setTitle(getString(R.string.osm_marker_title));
                positionMarker.setSnippet("Latitude: " + gp.getLatitude() + "\n" + "Longitude: " + gp.getLongitude());
                positionMarker.setImage(res.getDrawable(entryImgs[type]));
                Drawable[] iconLayer = new Drawable[2];
                iconLayer[0] = res.getDrawable(R.mipmap.ic_poi);
                iconLayer[1] = res.getDrawable(entryImgs[type]);
                LayerDrawable icon = new LayerDrawable(iconLayer);
                positionMarker.setIcon(icon);
                //positionMarker.setIcon(res.getDrawable(entryImgs[type]));
                mapView.getOverlays().add(positionMarker);
                mapView.invalidate();
            }
        } else {
            iv.setColorFilter(Color.argb(200, 185, 185, 185));
            iv.setTag("disabled");
            tv.setTypeface(null, Typeface.NORMAL);
            Toaster("You disabled " + entries[position]);
            for(int i=0; i<poiMarkers.size(); ++i){
                Poi poi = poiMarkers.get(i);
                if(poi.getType() == type){
                    poiMarkers.remove(i);
                    mapView.getOverlays().remove(i);
                }
            }
        }
    }

    private int getType(int position){
        int type;
        switch (position){
            case 0:
                type = Types.FOUNTAIN;
                break;
            case 1:
                type = Types.PATH;
                break;
            case 2:
                type = Types.BREAK_POINT;
                break;
            case 3:
                type = Types.TRASH_BIN;
                break;
            case 4:
                type = Types.PIC;
                break;
            case 5:
                type = Types.CELL_RECEPTION;
                break;
            case 6:
                type = Types.WIFI;
                break;
            case 7:
                type = Types.LIFT;
                break;
            default:
                type = 0;
                break;
        }
        return type;
    }

    private void initGps(){
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        boolean isLocationEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if(!isLocationEnabled){
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
        Criteria criteria = new Criteria();
        provider = locationManager.getBestProvider(criteria, false);
        mLocation = locationManager.getLastKnownLocation(provider);
    }

    private void Toaster(String text){
        Toaster(text, false);
    }

    private void Toaster(String text, boolean longDuration){
        if(longDuration) Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
        else Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
    }

    private void addSimpleMarker(GeoPoint gp){
        Marker positionMarker = new Marker(mapView);
        positionMarker.setPosition(gp);
        positionMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
        positionMarker.setTitle(getString(R.string.osm_marker_title));
        positionMarker.setSnippet("Latitude: " + gp.getLatitude() + "\n" + "Longitude: " + gp.getLongitude());
        mapView.getOverlays().add(positionMarker);
        mapView.invalidate();
    }

    @Override
    public void onLocationChanged(Location location) {
        mLocation = location;
        if(mLocation == null) return;

        double lat = location.getLatitude();
        double lon = location.getLongitude();
        GeoPoint gp = new GeoPoint(lat, lon);

        addSimpleMarker(gp);

        mapController.setCenter(gp);

        //TODO Move this to the not-yet-implemented upload method
        weatherClient.getCurrentCondition(new WeatherRequest(lon, lat), new WeatherClient.WeatherEventListener() {
            @Override
            public void onWeatherRetrieved(CurrentWeather weather) {
                Log.d(TAG, "City [" + weather.weather.location.getCity() + "] Current temp: " + weather.weather.temperature.getTemp());
            }

            @Override
            public void onWeatherError(WeatherLibException wle) {
                Log.e(TAG, "Weather error - parsing data");
                wle.printStackTrace();
            }

            @Override
            public void onConnectionError(Throwable t) {
                Log.e(TAG, "Connection Error");
                t.printStackTrace();
            }
        });
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    public class InformDialog extends DialogFragment {
        private String title;
        private String msg;

        public InformDialog(String title, String msg){
            this.title = title;
            this.msg = msg;
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle(title)
                    .setMessage(msg)
                    .setCancelable(false)
            .setPositiveButton(R.string.inform_positive_button, null);
            return builder.create();
        }
    }

    public class AddPoiDialog extends DialogFragment {
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle(R.string.add_poi_dialog_title)
                    .setAdapter(new ImageListAdapter(MainActivity.this, entries, entryImgs), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            switch (which) {
                                case 0:
                                    AddFountainDialog addFountainDialog = new AddFountainDialog();
                                    addFountainDialog.show(getFragmentManager(), "Add fountain POI Dialog");
                                    break;
                            }
                        }
                    });
            return builder.create();
        }
    }

    public class AddFountainDialog extends DialogFragment {
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle(R.string.fountain_size_dialog_title)
                    .setAdapter(new ImageListAdapter(MainActivity.this, fountainSizes, fountainImgs), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //Add POI to DB
                            double _lat = mLocation.getLatitude();
                            double _lon = mLocation.getLongitude();
                            double _alt = mLocation.getAltitude();
                            int _type = Types.FOUNTAIN;
                            long _time = System.currentTimeMillis() / 1000;
                            Poi poi = new Poi(_lat, _lon, _alt, _type, _time);
                            long rowId = dbHandler.addPoi(poi);

                            if(rowId >= 0) Toaster(getString(R.string.add_poi_success), true);

                            int size = 0;
                            switch (which) {
                                case 0:
                                    size = Features.SMALL;
                                    break;
                                case 1:
                                    size = Features.MEDIUM;
                                    break;
                                case 2:
                                    size = Features.LARGE;
                                    break;
                                default:
                                    Log.e(TAG, "Wrong fountain size " + which);
                            }

                            //TODO Add POI properties to DB
                            dbHandler.addPoiOptions(rowId, size);

                            Log.d(TAG, "Entries in POI: " + dbHandler.getPoiCount());
                            List<Poi> pois = dbHandler.getAllPois();
                            for (int i = 0; i < pois.size(); ++i) {
                                Poi p = pois.get(i);
                                Log.d(TAG, i + ": " + poi.getLat() + ", " + poi.getLon());
                            }
                        }
                    });
            return builder.create();
        }
    }

    private class ImageListAdapter extends ArrayAdapter<String> {

        private final Activity context;
        private final String[] texts;
        private final Integer[] imgs;

        public ImageListAdapter(Activity context, String[] texts, Integer[] imgs) {
            super(context, R.layout.drawer_list_item, texts);
            this.context = context;
            this.texts = texts;
            this.imgs = imgs;
        }

        @Override
        public View getView(int position, View view, ViewGroup parent) {
            LayoutInflater inflater = context.getLayoutInflater();
            View rowView= inflater.inflate(R.layout.drawer_list_item, null, true);
            TextView txtTitle = (TextView) rowView.findViewById(R.id.toggleEntryDesc);

            ImageView imageView = (ImageView) rowView.findViewById(R.id.toggleEntryImg);
            txtTitle.setText(texts[position]);

            imageView.setImageResource(imgs[position]);
            return rowView;
        }
    }

    @Override
    public void setTitle(CharSequence title){
        mTitle = title;
        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null) actionBar.setTitle(mTitle);
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        locationManager.requestLocationUpdates(provider, GPS_MIN_TIME, GPS_MIN_DIST, this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        locationManager.removeUpdates(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    public void restoreActionBar() {
        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setTitle(mTitle);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            return  inflater.inflate(R.layout.fragment_main, container, false);
        }
    }

}