654a4dc1f708a187ec7a35c948ed201f059f16b4
[DHBWCampusApp.git] / app / src / main / java / de / dhbwloe / campusapp / CampusApp.java
1 /* CampusApp.java
2  *
3  * This program is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 package de.dhbwloe.campusapp;
17
18 import android.content.Context;
19 import android.content.Intent;
20 import android.nfc.NfcAdapter;
21 import android.os.Bundle;
22 import android.support.design.widget.FloatingActionButton;
23 import android.support.design.widget.Snackbar;
24 import android.support.v4.app.FragmentActivity;
25 import android.util.Log;
26 import android.view.KeyEvent;
27 import android.view.View;
28 import android.support.design.widget.NavigationView;
29 import android.support.v4.view.GravityCompat;
30 import android.support.v4.widget.DrawerLayout;
31 import android.support.v7.app.ActionBarDrawerToggle;
32 import android.support.v7.app.AppCompatActivity;
33 import android.support.v7.widget.Toolbar;
34 import android.view.Menu;
35 import android.view.MenuItem;
36 import android.view.inputmethod.EditorInfo;
37 import android.view.inputmethod.InputMethodManager;
38 import android.widget.EditText;
39 import android.widget.ImageView;
40 import android.widget.LinearLayout;
41 import android.widget.TextView;
42
43 import java.util.Date;
44
45 import de.dhbwloe.campusapp.nfcreader.NfcCardListener;
46
47 public class CampusApp extends FragmentActivity {
48
49     private boolean bSearchActive = false;
50     private CampusAppContext AppContext = null;
51
52     /*
53     * Dev Info:
54     *
55     * Die App besteht aus einer einzigen Activity, auf welcher dynamisch Fragmente platziert werden.
56     * Das Menü, sowie die Headerleiste befinden sich auf der Activity, sind dementsprechend immer verfügbar.
57     *
58     * Zur laufzeit der App wird eine einzige Instanz der Klasse CampusAppContext angelegt.
59     * Dieser Kontext dient als einstiegspunkt für sämmtliche global verfügbaren verwaltungs tools.
60     * Dazu gehören:
61     *   AppContext.getNavigationManager()    NavigationManager   Verwaltet die angezeigten Fragmente und deren Navigation
62     *                                                            .navigatePage("Dashboard")  to navigate to the Dashboard
63     *   ... to be continued ...
64      */
65
66     @Override
67     protected void onCreate(Bundle savedInstanceState) {
68         Log.i("CampusApp", "Event: onCreate");
69         super.onCreate(savedInstanceState);
70         setContentView(R.layout.activity_campus_app);
71
72         // Erstelle neuen AppContext, wenn keiner existiert
73         AppContext = CampusAppContext.getInstance();
74         if(AppContext == null)
75             AppContext = new CampusAppContext(this, R.id.fragment_container);
76         else
77             AppContext.setMainActivity(this);
78
79         // Wenn die App aus dem Ruhezustand (oder auch Orientation change) reaktiviert wird soll nicht zuerst der Splashscreen angezeigt werden.
80         boolean instantRestore = false;
81         if(savedInstanceState != null) {
82             long lastrun = savedInstanceState.getLong("lastrun");
83             lastrun = ((new Date()).getTime()/1000) - lastrun;
84             Log.i("CampusApp", "Restored from Idle state! Idled: "+lastrun+" secs");
85             if(lastrun < 30) {
86                 instantRestore = true;
87
88                 // restore previous Title
89                 AppContext.setTitle(savedInstanceState.getString("activetitle"));
90             }
91
92
93             Bundle contextVars = savedInstanceState.getBundle("savedContextVariables");
94             if(contextVars != null) {
95                 Bundle contextVariables = AppContext.getContextVariables();
96                 contextVariables.putAll(contextVars);
97             }
98         }
99
100         prepareMainUi();
101         if(instantRestore) // orientation change
102             loadMainUi();
103         else
104             // don't add navigation to SlashScreen, or even from SplashScreen to Dashboard to the history log!
105             // it would be very strange to return to the SplashScreen or an "empty" page on return ;)
106             AppContext.getNavigationManager().navigatePage("SplashScreen", null, false);
107
108     }
109
110     @Override
111     public void onSaveInstanceState(Bundle savedInstanceState) {
112         Log.i("CampusApp", "Event: onSaveInstanceState");
113
114         // Save instance state during "restarts" due to orientation changes.
115         // We don't want to see the splash screen everytime the orientation changes ;)
116         savedInstanceState.putLong("lastrun", (new Date()).getTime() / 1000);
117         savedInstanceState.putString("activepage", AppContext.getNavigationManager().getCurrentPageName());
118         TextView titleView = (TextView) findViewById(R.id.title);
119         savedInstanceState.putString("activetitle", titleView.getText().toString());
120
121         Bundle contextVariables = AppContext.getContextVariables();
122         savedInstanceState.putBundle("savedContextVariables", contextVariables);
123
124         // Always call the superclass so it can save the view hierarchy state
125         super.onSaveInstanceState(savedInstanceState);
126     }
127
128     public void prepareMainUi() {
129         ImageView btnOpenSearch = (ImageView) findViewById(R.id.search_button);
130         btnOpenSearch.setVisibility(View.GONE);
131     }
132
133     public void loadMainUi() {
134         ImageView btnOpenSearch = (ImageView) findViewById(R.id.search_button);
135
136         btnOpenSearch.setVisibility(View.VISIBLE);
137         setupActionBar();
138         setupSearchTriggers();
139
140         AppContext.getNfcCardListener().startNfcListener();
141     }
142
143     private void setupActionBar() {
144         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
145         DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
146         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
147         drawer.setDrawerListener(toggle);
148         toggle.syncState();
149
150         NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
151         navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
152             @SuppressWarnings("StatementWithEmptyBody")
153             @Override
154             public boolean onNavigationItemSelected(MenuItem item) {
155                 // Handle navigation view item clicks here.
156                 int id = item.getItemId();
157
158                 switch (id) { // Navigation Items from res/menu/activity_campus_app_drawer.xml
159                     case R.id.nav_dashboard:
160                         AppContext.getNavigationManager().navigatePage("Dashboard");
161                         break;
162                     case R.id.nav_vorlesungsplan:
163                         AppContext.getNavigationManager().navigatePage("Vorlesungsplan");
164                         break;
165                     case R.id.nav_mensa:
166                         AppContext.getNavigationManager().navigatePage("Mensa");
167                         break;
168                     case R.id.nav_news:
169                         AppContext.getNavigationManager().navigatePage("News");
170                         break;
171                     case R.id.nav_settings:
172                         AppContext.getNavigationManager().navigatePage("Settings");
173                         break;
174                     case R.id.nav_wifi:
175                         AppContext.getNavigationManager().navigatePage("WifiSettings");
176                         break;
177                     case R.id.nav_impressum:
178                         AppContext.getNavigationManager().navigatePage("Impressum");
179                         break;
180                     default:
181                         return false;
182                 }
183
184                 DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
185                 drawer.closeDrawer(GravityCompat.START);
186                 return true;
187             }
188         });
189     }
190
191     private void setupSearchTriggers() {
192         ImageView btnOpenSearch = (ImageView) findViewById(R.id.search_button);
193         ImageView btnCloseSearch = (ImageView) findViewById(R.id.search_clear);
194         EditText edtSearchInput = (EditText) findViewById(R.id.search_input);
195         TextView txtTitle = (TextView) findViewById(R.id.title);
196
197         // EventListener für Suchfunktion
198         btnOpenSearch.setOnClickListener(new View.OnClickListener() {
199             @Override
200             public void onClick(View view) {
201                 triggerSearchPanel(true);
202             }
203         });
204         edtSearchInput.setOnFocusChangeListener(new View.OnFocusChangeListener() {
205             @Override
206             public void onFocusChange(View v, boolean hasFocus) {
207                 EditText edtSearchInput = (EditText) v;
208                 if (!hasFocus && edtSearchInput.getText().length() == 0) {
209                     triggerSearchPanel(false);
210                 }
211             }
212         });
213         edtSearchInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
214             @Override
215             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
216                 if (actionId == EditorInfo.IME_ACTION_SEARCH) {
217                     EditText edtSearchInput = (EditText) v;
218                     triggerSearchAction(edtSearchInput.getText().toString());
219                     triggerSearchPanel(false);
220                     return true;
221                 }
222                 return false;
223             }
224         });
225         btnCloseSearch.setOnClickListener(new View.OnClickListener() {
226             @Override
227             public void onClick(View view) {
228                 EditText edtSearchInput = (EditText) findViewById(R.id.search_input);
229                 edtSearchInput.setText("");
230                 triggerSearchPanel(false);
231             }
232         });
233         txtTitle.setOnClickListener(new View.OnClickListener() {
234             @Override
235             public void onClick(View view) {
236                 triggerSearchPanel(true);
237             }
238         });
239
240     }
241
242     private void triggerSearchPanel(boolean show) {
243         if(bSearchActive == show)
244             return;
245         bSearchActive = show;
246         LinearLayout layTitleContainer = (LinearLayout) findViewById(R.id.title_container);
247         LinearLayout laySearchContainer = (LinearLayout) findViewById(R.id.search_container);
248         EditText edtSearchInput = (EditText) findViewById(R.id.search_input);
249
250         InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
251         if(show) {
252             layTitleContainer.setVisibility(View.GONE);
253             laySearchContainer.setVisibility(View.VISIBLE);
254             edtSearchInput.requestFocus();
255
256             imm.showSoftInput(edtSearchInput, InputMethodManager.SHOW_IMPLICIT);
257         } else {
258             layTitleContainer.setVisibility(View.VISIBLE);
259             laySearchContainer.setVisibility(View.GONE);
260
261             View view = this.getCurrentFocus();
262             if (view != null) {
263                 imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
264             }
265         }
266     }
267
268     private void triggerSearchAction(String query) {
269         Bundle bundle = new Bundle();
270         bundle.putString("query", query);
271
272         AppContext.getNavigationManager().navigatePage("AppSearch", bundle);
273     }
274
275     @Override
276     public void onBackPressed() {
277         DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
278         if (drawer.isDrawerOpen(GravityCompat.START)) {
279             drawer.closeDrawer(GravityCompat.START);
280         } else if(!AppContext.getNavigationManager().back()) {
281             super.onBackPressed(); // trigger system action if internal navigation manager returns false for back()
282         }
283     }
284
285     @Override
286     public boolean onCreateOptionsMenu(Menu menu) {
287         // Inflate the menu; this adds items to the action bar if it is present.
288         getMenuInflater().inflate(R.menu.campus_app, menu);
289         return true;
290     }
291
292     @Override
293     public boolean onOptionsItemSelected(MenuItem item) {
294         // Handle action bar item clicks here. The action bar will
295         // automatically handle clicks on the Home/Up button, so long
296         // as you specify a parent activity in AndroidManifest.xml.
297         int id = item.getItemId();
298
299         //noinspection SimplifiableIfStatement
300         if (id == R.id.action_settings) {
301             return true;
302         }
303
304         return super.onOptionsItemSelected(item);
305     }
306
307     /* nfc listener related callbacks */
308     @Override
309     public void onResume() {
310         if(AppContext == null)
311             AppContext = new CampusAppContext(this, R.id.fragment_container);
312         else
313             AppContext.setMainActivity(this);
314
315         super.onResume();
316         Log.i("CampusApp", "onResume event");
317         AppContext.getNfcCardListener().resumeForefrontDispatcher();
318     }
319
320     @Override
321     public void onPause() {
322         super.onPause();
323         Log.i("CampusApp", "Event: onPause");
324         AppContext.getNfcCardListener().pauseForefrontDispatcher();
325     }
326
327     @Override
328     public void onNewIntent(Intent intent) {
329         if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
330             AppContext.getNfcCardListener().handleNfcEvent(intent);
331         }
332     }
333
334 }