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