/* Copyright 2014-2023 askanimus@gmail.com */

/* This File is part of "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) 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.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) 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 "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).  If not, see <http://www.gnu.org/licenses/>.
 *
 * Diese Datei ist Teil von "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) ist Freie Software: Sie können es unter den Bedingungen
 * der GNU General Public License, wie von der Free Software Foundation,
 * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
 * veröffentlichten Version, weiter verteilen und/oder modifizieren.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) wird in der Hoffnung, dass es nützlich sein wird, aber
 * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
 * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
 * Siehe die GNU General Public License für weitere Details.
 *
 * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
 * Programm erhalten haben. Wenn nicht, siehe <https://www.gnu.org/licenses/>.
 */
package askanimus.arbeitszeiterfassung2;

import static askanimus.arbeitszeiterfassung2.setup.ASettings.aktDatum;
import static askanimus.arbeitszeiterfassung2.setup.ASettings.aktJob;
import static askanimus.arbeitszeiterfassung2.setup.ASettings.getLetzterAnzeigeTag;
import static askanimus.arbeitszeiterfassung2.setup.ASettings.jobListe;
import static askanimus.arbeitszeiterfassung2.setup.ASettings.letzterAnzeigeTag;
import static askanimus.arbeitszeiterfassung2.setup.ASettings.mPreferenzen;
import static askanimus.arbeitszeiterfassung2.setup.ASettings.res;
import static askanimus.arbeitszeiterfassung2.setup.ASettings.setAktivJob;
import static askanimus.arbeitszeiterfassung2.setup.ASettings.zustand;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.appwidget.AppWidgetManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.core.view.WindowCompat;
import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import askanimus.arbeitszeiterfassung2.arbeitsjahr.ArbeitsjahrPager;
import askanimus.arbeitszeiterfassung2.arbeitsmonat.ArbeitsmonatPager;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.ArbeitsplatzFragment;
import askanimus.arbeitszeiterfassung2.arbeitstag.ArbeitstagExpandListAdapter;
import askanimus.arbeitszeiterfassung2.arbeitstag.ArbeitstagFragment;
import askanimus.arbeitszeiterfassung2.arbeitstag.ArbeitstagPager;
import askanimus.arbeitszeiterfassung2.arbeitswoche.ArbeitswocheFragment;
import askanimus.arbeitszeiterfassung2.arbeitswoche.ArbeitswochePager;
import askanimus.arbeitszeiterfassung2.charts.ChartsFragment;
import askanimus.arbeitszeiterfassung2.datenbank.Bereinige_Datenbank;
import askanimus.arbeitszeiterfassung2.datenbank.DatenbankHelper;
import askanimus.arbeitszeiterfassung2.datensicherung.AAutoBackup;
import askanimus.arbeitszeiterfassung2.datensicherung.Datensicherung_Activity;
import askanimus.arbeitszeiterfassung2.export.ExportActivity;
import askanimus.arbeitszeiterfassung2.export.IExport_Basis;
import askanimus.arbeitszeiterfassung2.feiertage.FeiertageFragment;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.setup.ISettings;
import askanimus.arbeitszeiterfassung2.setup.LocaleHelper;
import askanimus.arbeitszeiterfassung2.setup.SettingsActivity;
import askanimus.arbeitszeiterfassung2.stempeluhr.StempeluhrFragment;
import askanimus.arbeitszeiterfassung2.stempeluhr.StempeluhrStatus;
import askanimus.arbeitszeiterfassung2.suche.Suche_Activity;
import askanimus.arbeitszeiterfassung2.widget.Widget;

public class MainActivity
        extends 
        AppCompatActivity 
        implements
        NavigationDrawerFragment.NavigationDrawerCallbacks,
        ArbeitstagExpandListAdapter.ArbeitstagListeCallbacks,
        ArbeitstagFragment.ArbeitstagMainCallbacks,
        ArbeitswocheFragment.ArbeitsWocheMainCallbacks,
        ISettings{
    private StorageHelper mStorageHelper;

    /**
     * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
     */
    private NavigationDrawerFragment mNavigationDrawerFragment;

    /*
        wird zum anpassen der App Sprache benötigt, wenn diese von der Systemsprache abweicht
     */
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(getApplicationContext());
        setTheme(prefs.getBoolean(ASettings.KEY_THEMA_DUNKEL, false) ?
                R.style.MyAppTheme :
                R.style.MyAppTheme_Light
        );

        setContentView(R.layout.activity_main);

        // allgem. Steuerung und Navigation
        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        // Set up the drawer.
        assert mNavigationDrawerFragment != null;
        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                findViewById(R.id.drawer_layout));

        // ist NFC vorhanden und eingeschaltet wenn der User NFC benötigt
        if (prefs.getBoolean(KEY_NFC_AKTIV + prefs.getLong(KEY_JOBID, 0), false)) {
            NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
            // Prüfen ob NFC  vorhanden und eingeschaltet ist
            if (nfcAdapter != null) {
                if (!nfcAdapter.isEnabled()) {
                    // beim User nachfragen, ob NFC eingeschaltet werden soll
                    openNfcSettings();
                }
            }
        }

        getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() {
                backPressed();
            }
        });

        try {
            ASettings.appVersionCode = getApplicationContext()
                    .getPackageManager()
                    .getPackageInfo(getApplicationContext().getPackageName(), 0)
                    .versionCode;
            ASettings.appVersionName = getApplicationContext()
                    .getPackageManager()
                    .getPackageInfo(getApplicationContext().getPackageName(), 0)
                    .versionName;
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(e);
        }

        /*// Empfange Daten behandeln
        Intent intent = getIntent();
        String action = intent.getAction();
        String type = intent.getType();

        if (IIcs.DATEI_TYP_ICS.equals(type)) {
            Uri uri = null;
            if(Intent.ACTION_SEND.equals(action)){
                uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
            } else if(Intent.ACTION_VIEW.equals(action)) {
                uri = intent.getData();
            }

            if (uri != null) {
                // Datenbank erzeugen, falls noch nicht geschehen und öffnen
                if (ASettings.feiertage == null) {
                    if (ASettings.stundenDBHelper == null) {
                        ASettings.stundenDBHelper = new DatenbankHelper(this);
                    }

                    if (ASettings.mDatenbank == null || !ASettings.mDatenbank.isOpen()) {
                        ASettings.mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();
                    }
                    ASettings.feiertage = new FeiertageListe(ASettings.mDatenbank);
                }
                ArrayList<Feiertag> listeImport = ASettings.feiertage.FeiertageIcsImport(this, uri);
                if (listeImport != null) {
                    int anzahl = ASettings.feiertage.FeiertageListeImport(listeImport);
                    Toast.makeText(
                            this,
                            String.format(
                                    Locale.getDefault(),
                                    "%d %s",
                                    anzahl,
                                    getString(R.string.toast_import_erfolg)
                            ),
                            Toast.LENGTH_LONG
                    ).show();
                    intent.putExtra(KEY_ANZEIGE_VIEW, VIEW_FEIERTAGE);
                    intent.putExtra(KEY_ANZEIGE_DATUM, new Date().getTime());
                } else {
                    Toast.makeText(this, getString(R.string.toast_import_miserfolg), Toast.LENGTH_LONG).show();
                }
            }
        }*/
    }

    @Override
    public void onResume() {
        super.onResume();
        String mAction = getIntent().getAction();
        if (APP_RESET.equals(mAction)) {
            zustand = INIT_ZUSTAND_UNGELADEN;
        }
        ASettings.init(this, this::resume);
    }

    private void resume() {
        // die Werte des aktuellen Arbeitsplatzes einlesen
        // Beim ersten Start der App neuen Job mit Defaultwerten anlegen
        if (mPreferenzen.contains(KEY_INIT_FINISH)) {
            // das Fragment für NFC Einstellungen ist nicht mehr offen
            ASettings.mPreferenzen.edit().putBoolean(ISettings.KEY_NFC_EDIT, false).apply();

            // Aktuelles Datum setzen und Zeitwerte auf 0 setzen
            aktDatum.set(new Date());

            // den letzten Tag auf den aktuellen Tag setzen
            letzterAnzeigeTag.set(getLetzterAnzeigeTag(aktJob).getCalendar());

            SharedPreferences.Editor mEdit = mPreferenzen.edit();

            //
            // In Version 1.02.93 ist die Option für Dezimalminuten von den allgem. Einstellungen in
            // die Einstellungen des arbeitsplatz gewandert
            // Alle Arbeitsplätze inkl. den schon geladenen aktuellen müssen nun aktuallisiert werden
            //
            if (mPreferenzen.contains(KEY_ANZEIGE_DEZIMAL)) {
                boolean dezimal = mPreferenzen.getBoolean(KEY_ANZEIGE_DEZIMAL, true);
                //ArbeitsplatzListe aListe = new ArbeitsplatzListe(Einstellungen.aktJob);
                ArrayList<Arbeitsplatz> al = jobListe.getListe();
                if (al != null) {
                    for (Arbeitsplatz a : al) {
                        a.setOption(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL, dezimal);
                        a.schreibeJob();
                    }
                    mEdit.remove(KEY_ANZEIGE_DEZIMAL).apply();
                }
            }

            // wenn die App mit einer bestimmten Ansicht und einen bestimmten Datum geöffnet werden soll
            Bundle extras = getIntent().getExtras();
            long openDatum;
            int openView;

            if (extras != null && extras.containsKey(KEY_ANZEIGE_VIEW)) {
                // die Activity wurde mit einen konkreten Datum und arbeitsplatz aufgerufen
                // z.B.: von der suche Activity oder Stempeluhr
                if (extras.getLong(KEY_JOBID) != aktJob.getId()) {
                    setAktivJob(extras.getLong(KEY_JOBID));
                }

                openDatum = extras.getLong(KEY_ANZEIGE_DATUM);
                openView = extras.getInt(KEY_ANZEIGE_VIEW);
            } else {
                // Bevorzugte Ansicht öffnen
                if (mPreferenzen.getInt(KEY_ANZEIGE_VIEW, VIEW_TAG) == VIEW_LETZTER ||
                        mPreferenzen.getBoolean(KEY_RESUME_VIEW, false)) {
                    // Nach Rückkehr aus anderer Activity z.B.: Datenesicherung, export, Einstellungen
                    // oder wenn als bevorzugte Ansicht die letzte offene Ansicht gewählt ist
                    // zur letzten Ansicht (Tag oder Woche etc. und Datum) springen
                    mEdit.putBoolean(KEY_RESUME_VIEW, false).apply();

                    openDatum = mPreferenzen.getLong(KEY_ANZEIGE_DATUM, aktDatum.getTimeInMillis());
                    openView = mPreferenzen.getInt(KEY_ANZEIGE_LETZTER, VIEW_TAG);
                } else {

                    openDatum = aktDatum.getTimeInMillis();
                    openView = mPreferenzen.getInt(KEY_ANZEIGE_VIEW, VIEW_TAG);
                }
            }

            if (openView == VIEW_TAG && aktJob.isEndeAufzeichnung(aktDatum)) {
                openView = VIEW_MONAT;
            }
            OpenView(openView, openDatum);

            long alteVersion = mPreferenzen.getLong(KEY_VERSION_APP, 0);

            // Widgets neu zeichnen wenn die App von den Einstellungen zurückkehrt oder nach einen Update neu gestartet wurde
            if (mPreferenzen.getBoolean(KEY_RESUME_VIEW, false) || alteVersion < ASettings.appVersionCode) {
                AppWidgetManager wm = AppWidgetManager.getInstance(this);
                ComponentName cn = new ComponentName(getPackageName(), Widget.class.getName());
                wm.notifyAppWidgetViewDataChanged(wm.getAppWidgetIds(cn), R.layout.widget2x4);

                // neu Zeichnen der Stempeluhren anstoßen
                //Stempeluhr.updateAllWidgets(this);
            }
            //
            // Fehlerkorrekturen und Anzeige der Versionshinweise
            //
            if (alteVersion < ASettings.appVersionCode) {
                if (alteVersion <= 205018) {
                    /*
                     * alle Einstellungen zu Zeilen und Spalten der PDF Berichte werden zurück gesetzt
                     * und ab sofort im Arbeitsplatz gespeichert weil es zu Darstellungsproblemen gekommet
                     * wenn in den Arbeitsplätzen unterschiedliche Zusatzspalten vorliegen
                     */
                    // Monatsberichte
                    mEdit.remove(KEY_EXP_M_SPALTEN_LGAV);
                    mEdit.remove(KEY_EXP_M_ZEILEN_LGAV);
                    mEdit.remove(KEY_EXP_M_ZUSATZ_LGAV);
                    mEdit.remove(KEY_EXP_M_SPALTEN_KURZ);
                    mEdit.remove(KEY_EXP_M_ZEILEN_KURZ);
                    mEdit.remove(KEY_EXP_M_ZUSATZ_KURZ);
                    mEdit.remove(KEY_EXP_M_SPALTEN_AUSF);
                    mEdit.remove(KEY_EXP_M_ZEILEN_AUSF);
                    mEdit.remove(KEY_EXP_M_ZUSATZ_AUSF);
                    // Einsatzortberichte
                    mEdit.remove(KEY_EXP_EO_SPALTEN);
                    mEdit.remove(KEY_EXP_EO_ZEILEN);
                    mEdit.remove(KEY_EXP_EO_ZUSATZ);
                    // Wochenberichte
                    mEdit.remove(KEY_EXP_W_SPALTEN);
                    mEdit.remove(KEY_EXP_W_ZEILEN);
                    mEdit.remove(KEY_EXP_W_ZUSATZ);
                    // Zeitraumberichte
                    mEdit.remove(KEY_EXP_ZR_SPALTEN);
                    mEdit.remove(KEY_EXP_ZR_ZEILEN);
                    mEdit.remove(KEY_EXP_ZR_ZUSATZ).apply();
                }

                if (alteVersion < 202009) {
                    /*
                     * Ein Fehler beim setzen dieser Variablen trat in der Vorversion ein Fehler auf.
                     * Desshalb wird die Userentscheidung wieder gelöscht
                     */
                    mPreferenzen.edit().remove(ISettings.KEY_ANTWORT_DEZ).apply();
                }

                if (alteVersion < 208013) {
                    // der Wert für den Offset zwischen den Backups wird nun in den Wert gespeichert
                    // der das nächste Backup aufnehmen sollte
                    AAutoBackup.init(
                            this,
                            mPreferenzen.getInt(KEY_AUTOBACKUP_INTERVAL, AUTOBACKUP_NO),
                            mPreferenzen.getInt(KEY_AUTOBACKUP_SCHRITTE, 1));
                } else {
                    // Autobabackup Timer neu setzen
                    AAutoBackup.updateTimer(this);
                }

                // Überzählige Einträge in Einstellungen Tabelle löschen
                // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();

                String count = "SELECT "
                        + DatenbankHelper.DB_F_ID
                        + " FROM "
                        + DatenbankHelper.DB_T_SETTINGS;
                Cursor result = ASettings.mDatenbank.rawQuery(count, null);

                while (result.moveToNext()) {
                    @SuppressLint("Range")
                    long id = result.getLong(result.getColumnIndex(DatenbankHelper.DB_F_ID));
                    if (id != 1) {
                        ASettings.mDatenbank.delete(
                                DatenbankHelper.DB_T_SETTINGS,
                                DatenbankHelper.DB_F_ID + "=?",
                                new String[]{Long.toString(id)}
                        );
                    }
                }
                result.close();

                // Die fehlerhafte Funktion der Tagesupdates führte zu unzähligen leeren Monaten
                // und zu einer aufgeblähten Datenbank, diese leeren Monate werden nun gelöscht
                if (alteVersion < 208017) {
                    Bereinige_Datenbank cleanDB = new Bereinige_Datenbank(this);
                    cleanDB.reinigung();
                }

                // Anzeige Versionsdialog
                new AlertDialog.Builder(this)
                        .setTitle(getString(R.string.version_info_titel, ASettings.appVersionName))
                        .setPositiveButton(android.R.string.ok, null)
                        .setView(R.layout.fragment_version_info)
                        .show();
                //}

                // neue Version in die Einstellungen schreiben
                mEdit.putLong(KEY_VERSION_APP, ASettings.appVersionCode).apply();
            }

            // NFC Handler registrieren
            /*if(nfcAdapter != null && nfcAdapter.isEnabled()) {
                setupForegroundDispatch(this, nfcAdapter);
            }*/
        } else {
            // Version der App in die Einstellungen schreiben
            mPreferenzen.edit().putLong(KEY_VERSION_APP, ASettings.appVersionCode).apply();

            // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();
            // Tabelle mit App Einstellungen initialisieren
            /*if(!ASettings.mDatenbank.isOpen())
               mDatenbank = ASettings.stundenDB.getWritableDatabase();*/

            String count = "SELECT count(*) FROM " + DatenbankHelper.DB_T_SETTINGS;
            Cursor result = ASettings.mDatenbank.rawQuery(count, null);
            result.moveToFirst();

            if (result.getInt(0) <= 0) {
                ContentValues mWerte = new ContentValues();
                mWerte.put(DatenbankHelper.DB_F_VERSION, ASettings.appVersionCode);
                mWerte.put(DatenbankHelper.DB_F_ID, 1);
                ASettings.mDatenbank.insert(DatenbankHelper.DB_T_SETTINGS, null, mWerte);
            }
            result.close();
            //// ASettings.mDatenbank.close();

            // den Assistenten zur Ersteinrichtung aufrufen
            Intent iAssistent = new Intent();
            iAssistent.setClass(this, SettingsActivity.class);
            iAssistent.putExtra(ARG_IS_INITASSIST, true);
            iAssistent.putExtra(KEY_EDIT_JOB, aktJob.getId());
            iAssistent.putExtra(KEY_INIT_SEITE, SETUP_SEITE_MIGRATION);
            iAssistent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(iAssistent);
        }

    }


    @Override
    public void onNavigationDrawerItemSelected(int position, Datum datum) {
        if (datum.liegtVor(aktJob.getStartDatum())) {
            OpenView(position, aktJob.getStartDatum().getTimeInMillis());
        } else if (datum.liegtNach(letzterAnzeigeTag)) {
            OpenView(position, letzterAnzeigeTag.getTimeInMillis());
        } else {
            OpenView(position, datum.getTimeInMillis());
        }
    }

    @Override
    public void onNavigationDrawerIconSelected(int icon) {
        if (icon == R.id.N_icon_hilfe)
            OpenTurorial();
    }

    // Bestimmtes Fragment öffnen
    void OpenView(int view, final long datum) {
        final Context mContext = this;

        if (mNavigationDrawerFragment.isDrawerOpen()) {
            mNavigationDrawerFragment.CloseDrawer();
        }

        // Den Inhalt der gewählten Seite anzeigen und den Titel anpassen
        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fInhalt = null;
        int mTitelID = 0;

        switch (view) {
            case VIEW_JOB:
                mTitelID = R.string.arbeitsplatz;
                fInhalt = ArbeitsplatzFragment.newInstance();
                break;
            case VIEW_JAHR:
                mTitelID = R.string.jahr;
                fInhalt = ArbeitsjahrPager.newInstance(datum);
                break;
            case VIEW_MONAT:
                mTitelID = R.string.monat;
                fInhalt = ArbeitsmonatPager.newInstance(datum);
                break;
            case VIEW_WOCHE:
                mTitelID = R.string.woche;
                fInhalt = ArbeitswochePager.newInstance(datum, this);
                break;
            case VIEW_TAG:
                if (ASettings.aktJob.isEndeAufzeichnung(ASettings.aktDatum)) {
                    new AlertDialog.Builder(this)
                            .setTitle(this.getString(R.string.ende_titel))
                            .setMessage(getString(R.string.dialog_open_tag,
                                    ASettings.aktJob.getEndDatum().getString_Datum(mContext)
                                    /*Einstellungen.datumsformat.format(Einstellungen.aktJob.getEndDatum().getTime())*/))
                            .setPositiveButton(this.getString(android.R.string.ok), (dialog, whichButton) -> {
                                //OpenView(Einstellungen.VIEW_MONAT, datum);
                            })
                            .setNeutralButton(this.getString(R.string.einstellungen), (dialog, whichButton) -> {
                                // Einstellungen öffnen
                                Intent iSettings = new Intent();
                                iSettings.setClass(mContext, SettingsActivity.class);
                                iSettings.putExtra(KEY_EDIT_JOB, ASettings.aktJob.getId());
                                iSettings.putExtra(ARG_NUR_JOB, true);
                                iSettings.putExtra(KEY_INIT_SEITE, SETUP_SEITE_ARBEITSPLATZ);
                                startActivity(iSettings);
                                finish();
                            }).show();
                } else {
                    mTitelID = R.string.tag;
                    fInhalt = ArbeitstagPager.newInstance(datum, this);
                }
                break;
            case VIEW_CHARTS:
                mTitelID = R.string.charts;
                int periode;
                if (ASettings.mPreferenzen.getInt(KEY_ANZEIGE_LETZTER, VIEW_MONAT) == VIEW_WOCHE) {
                    periode = ChartsFragment.PERIODE_WOCHE;
                } else {
                    periode = ChartsFragment.PERIODE_MONAT;
                }
                fInhalt = ChartsFragment.newInstance(
                        ASettings.mPreferenzen.getLong(
                                KEY_ANZEIGE_DATUM,
                                ASettings.aktDatum.getTimeInMillis()),
                        periode,
                        ChartsFragment.TYP_ABWESENHEITEN);
                break;
            case VIEW_STEMPELUHR:
                mTitelID = R.string.stempeluhr;
                Intent intent = getIntent();
                fInhalt = StempeluhrFragment.newInstance(
                        intent.getAction(),
                        intent.getLongExtra(StempeluhrStatus.KEY_STEMPELUHR_ID, 0)
                );
                break;
            case VIEW_FEIERTAGE:
                mTitelID = R.string.feiertage;
                fInhalt = FeiertageFragment.newInstance(datum);
                break;
            default:
                mTitelID = R.string.about;
                fInhalt = new AboutApp();
                //fInhalt = null;
        }

        // die neue Ansicht als letzte markieren
        SharedPreferences.Editor mEdit = ASettings.mPreferenzen.edit();
        mEdit.putInt(KEY_ANZEIGE_LETZTER, view);
        mEdit.putLong(KEY_ANZEIGE_DATUM, datum);
        mEdit.apply();

        if (fInhalt != null) {
            ActionBar actionBar = getSupportActionBar();

            if (actionBar != null) {
                actionBar.setTitle(mTitelID);

            }

            fragmentManager.beginTransaction()
                    .replace(R.id.container, fInhalt)
                    .commit();
        }

    }

    private void backPressed() {
        if (!mNavigationDrawerFragment.isDrawerOpen()) {
            boolean app_schliessen = false;
            int bevorzugte_Ansicht = ASettings.mPreferenzen.getInt(
                    KEY_ANZEIGE_VIEW,
                    VIEW_TAG
            );
            ;

            if (
                    bevorzugte_Ansicht == VIEW_TAG
                            && aktJob.isSetEnde()
                            && aktDatum.liegtNach(getLetzterAnzeigeTag(aktJob))
            ) {
                bevorzugte_Ansicht = VIEW_MONAT;
            }


            int aktuelle_Ansicht = ASettings.mPreferenzen.getInt(
                    KEY_ANZEIGE_LETZTER,
                    VIEW_TAG
            );

            Datum angezeigtes_Datum = aktJob.getAbrechnungsmonat(
                    new Datum(
                            ASettings.mPreferenzen.getLong(
                                    KEY_ANZEIGE_DATUM,
                                    aktDatum.getTimeInMillis()
                            ),
                            ASettings.aktJob.getWochenbeginn()
                    )
            );


            if (bevorzugte_Ansicht != VIEW_LETZTER) {
                if (bevorzugte_Ansicht == aktuelle_Ansicht) {
                    int periode;
                    switch (bevorzugte_Ansicht) {
                        case VIEW_JOB:
                            periode = -1;
                            break;
                        case VIEW_JAHR:
                            periode = Calendar.YEAR;
                            break;
                        case VIEW_WOCHE:
                            periode = Calendar.WEEK_OF_YEAR;
                            break;
                        case VIEW_MONAT:
                            periode = Calendar.MONTH;
                            break;
                        default:
                            periode = Calendar.DAY_OF_MONTH;
                    }

                    app_schliessen = (periode < 0 || angezeigtes_Datum.istGleich(
                            (aktJob.isEndeAufzeichnung(angezeigtes_Datum)) ?
                                    aktJob.getAbrechnungsmonat(letzterAnzeigeTag) :
                                    aktJob.getAbrechnungsmonat(aktDatum),
                            periode
                    ));
                }
            } else {
                app_schliessen = true;
            }

            if (app_schliessen) {
                if (!ASettings.mPreferenzen.getBoolean(KEY_ANTWORT_BEENDEN, false)) {
                    //final View vFrage = LayoutInflater.from(this).inflate(R.layout.fragment_dialog_frage_beenden, null);
                    AlertDialog.Builder aFrage = new AlertDialog.Builder(this);
                    aFrage.setMessage(R.string.dialog_frage_beenden);
                    //aFrage.setView(vFrage);
                    aFrage.setPositiveButton(R.string.beenden, (dialog, which) -> {
                        finish();
                    });
                    aFrage.setNegativeButton(R.string.beenden_ohne_frage, (dialog, which) -> {
                        // App ohne Nachfrage beenden
                        mPreferenzen.edit().putBoolean(KEY_ANTWORT_BEENDEN, true).apply();
                        finish();

                    });
                    aFrage.setNeutralButton(R.string.nicht_beenden, (dialog, which) -> {
                        // nichts machen, nur den Dialog schliessen
                    });
                    aFrage.create().show();
                } else {
                    finish();
                }
            } else {
                OpenView(bevorzugte_Ansicht, ASettings.aktDatum.getTimeInMillis());
            }

        } else {
            mNavigationDrawerFragment.CloseDrawer();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Bei Wechsel der Handyorientierung, den aktuellen View wiederherstellen
        ASettings.mPreferenzen.edit()
                .putBoolean(KEY_RESUME_VIEW, isChangingConfigurations()).apply();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            Intent iSettings = new Intent();
            iSettings.setClass(this, SettingsActivity.class);
            iSettings.putExtra(KEY_EDIT_JOB, ASettings.aktJob.getId());
            iSettings.putExtra(KEY_INIT_SEITE, SETUP_SEITE_ALLGEMEIN);
            iSettings.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            finish();
            startActivity(iSettings);
        } else if (id == R.id.action_export) {
            Intent iExport = new Intent();
            iExport.setClass(this, ExportActivity.class);
            iExport.putExtra(KEY_JOBID, ASettings.aktJob.getId());
            iExport.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            int seite = mPreferenzen.getInt(ISettings.KEY_ANZEIGE_LETZTER, ISettings.VIEW_WOCHE);
            seite = Math.min(-(seite - 3), VIEW_MONAT);
            iExport.putExtra(
                    KEY_ANZEIGE_VIEW,
                    seite
            );
            finish();
            startActivity(iExport);
        } else if (id == R.id.action_backup) {
            Intent iBackup = new Intent();
            iBackup.setClass(this, Datensicherung_Activity.class);
            iBackup.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            finish();
            startActivity(iBackup);
        } else if (id == R.id.action_about) {
            OpenView(VIEW_ABOUT, ASettings.mPreferenzen.getLong(KEY_ANZEIGE_DATUM, ASettings.aktDatum.getTimeInMillis()));
        } else if (id == R.id.action_suche) {
            OpenSuche();
        } else if (id == R.id.action_hilfe) {
            OpenTurorial();
        } else if (id == R.id.action_clean) {
            Bereinige_Datenbank cleanDB = new Bereinige_Datenbank(this);
            cleanDB.reinigung();
        } else if (id == R.id.action_feiertage){
            OpenView(VIEW_FEIERTAGE, ASettings.mPreferenzen.getLong(KEY_ANZEIGE_DATUM, ASettings.aktDatum.getTimeInMillis()));
        }

        return super.onOptionsItemSelected(item);
    }

    protected void OpenSuche() {
        final Dialog mDialog = new Dialog(this);

        mDialog.setTitle(R.string.suche);

        mDialog.setContentView(R.layout.fragment_suche);
        final SearchView mSuche = mDialog.findViewById(R.id.SU_suche);
        mSuche.setQueryHint(getString(R.string.suche));
        mSuche.setIconified(false);
        mSuche.setSubmitButtonEnabled(true);
        mSuche.setOnCloseListener(() -> {
            if (mSuche.getQuery().length() > 0)
                mSuche.clearFocus();
            else
                mDialog.dismiss();
            return true;
        });
        mSuche.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                String mSuchstring = mSuche.getQuery().toString();
                mSuche.clearFocus();
                mDialog.cancel();
                Intent iSuche = new Intent();
                iSuche.setClass(getApplicationContext(), Suche_Activity.class);
                iSuche.putExtra(KEY_SUCHE_STRING, mSuchstring);
                iSuche.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(iSuche);
                finish();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                return false;
            }
        });


        mDialog.show();
    }

    private void OpenTurorial() {
        // das Verzeichnis für das Handbuch prüfen/anlegen
        if (mStorageHelper == null) {
            String handbuchPfad;
            handbuchPfad = ASettings.mPreferenzen.getString(
                    ASettings.KEY_HANDBUCH_PFAD,
                    ASettings.mPreferenzen.getString(
                            ASettings.KEY_DATEN_DIR, "")
            );

            mStorageHelper = new StorageHelper(
                    this,
                    handbuchPfad,
                    null,
                    ISettings.KEY_HANDBUCH_PFAD,
                    true,
                    REQ_FOLDER_PICKER_WRITE_EXPORT/*,
                    this::OpenTurorial*/
            );
        }

        // ist das Verzeichnis vorhanden und beschreibbar
        if (mStorageHelper.isStorageMounted() && mStorageHelper.isWritheable()) {
            DocumentFile zielFile = mStorageHelper.getVerzeichnisFile().findFile(
                    res.getString(R.string.app_name) + "_Tutorial.pdf");

            Datum dFirst = new Datum(2016, 8, 4, aktJob.getWochenbeginn());

            // ist das Handbuch noch nicht am vorgesehnen Platz, dann dorthin kopieren
            if (zielFile == null || !zielFile.exists() || dFirst.liegtNach(new Datum(zielFile.lastModified(), aktJob.getWochenbeginn()))) {
                AssetManager assetManager = getAssets();
                InputStream in;
                OutputStream out;

                zielFile = mStorageHelper.getVerzeichnisFile().createFile(
                        IExport_Basis.DATEI_TYP_PDF,
                        res.getString(R.string.app_name) + "_Tutorial");

                if (zielFile != null) {
                    try {
                        out = getContentResolver().openOutputStream(zielFile.getUri());
                        if (out != null) {
                            in = assetManager.open("tutorial.pdf");

                            byte[] buffer = new byte[1024];
                            int read;
                            while ((read = in.read(buffer)) != -1) {
                                out.write(buffer, 0, read);
                            }
                            in.close();
                            out.flush();
                            out.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            // ist das Handbuch am vorgesehenen Platz
            if (zielFile != null && zielFile.exists() && zielFile.canRead()) {
                Intent intent = new Intent(Intent.ACTION_VIEW);

                Uri mURI = zielFile.getUri();//mStorageHelper.getDateiUri(zielFile.getName());
                //if (mURI != null) {
                intent.setDataAndType(mURI, IExport_Basis.DATEI_TYP_PDF);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                try {
                    PackageManager pm = getPackageManager();
                    if (intent.resolveActivity(pm) != null) {
                        startActivity(intent);
                    } else {
                        Toast.makeText(this, R.string.no_pdf_reader, Toast.LENGTH_LONG).show();
                    }
                } catch (ActivityNotFoundException e) {
                    Toast.makeText(this, R.string.no_pdf_reader, Toast.LENGTH_LONG).show();
                }
            } else {
                Toast.makeText(this, getString(R.string.no_handbuch_copy, mStorageHelper.getPfadSubtree()), Toast.LENGTH_LONG).show();
            }
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        requestCode = requestCode & 0x0000ffff;

        if (data != null && resultCode == RESULT_OK && requestCode == REQ_FOLDER_PICKER_WRITE_EXPORT) {
            if (data.getData() != null) {
                getContentResolver().takePersistableUriPermission(data.getData(),
                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                mStorageHelper.setPfad(data.getDataString());
                OpenTurorial();
            }
        }
    }


    /**
     * Rückmeldung vom Rechtemanagment nach Rechteanfrage
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
            requestCode = requestCode & 0x0000ffff;

            if (requestCode == REQ_DEMAND_WRITE) {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    // Recht verweigert, kein Handbuch anzeigen
                    Toast.makeText(
                            this,
                            getString(R.string.err_keine_berechtigung),
                            Toast.LENGTH_LONG
                    ).show();
                }
            }
        }
    }

    /*@Override
    protected void onPause() {
        if(nfcAdapter != null){
            nfcAdapter.disableForegroundDispatch(this);
        }
        super.onPause();
    }*/

   /* @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        String action = intent.getAction();
        if (APP_RESET.equals(action)) {
            zustand = INIT_ZUSTAND_UNGELADEN;
            //nfcTagListe = null;
        } else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
            handleNfcIntent(intent);
        } else if (ACTION_NFC_EDIT.equals(action)){
            Intent mSettingsIntent = new Intent();
            mSettingsIntent.setClass(this, SettingsActivity.class);
            mSettingsIntent.putExtra(ISetup.KEY_EDIT_JOB, aktJob.getId());
            mSettingsIntent.putExtra(ISetup.KEY_INIT_SEITE, 7);
            mSettingsIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(mSettingsIntent);
        }
    }
*/

    // NFC Funktionalität

    /**
     * NFC vom User einschalten lassen
     */
    private void openNfcSettings() {
        Intent intent;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            intent = new Intent(Settings.Panel.ACTION_NFC);
        } else {
            intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
        }
        startActivity(intent);
    }

    /**
     * Intent zum behandeln von angelegten NFC Tags registrieren
     * @param activity Activity, die darauf reagieren soll
     * @param adapter der NFC Adapter

    public void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
    final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    final PendingIntent pendingIntent = PendingIntent.getActivity(
    activity.getApplicationContext(),
    0,
    intent,
    PendingIntent.FLAG_MUTABLE);

    adapter.enableForegroundDispatch(activity, pendingIntent, null, null);
    }*/

    /**
     * Der Handler, der angelegte NFC Tags verarbeitet
     * @param intent

    public void handleNfcIntent(Intent intent) {
    if (nfcTagListe == null) {
    nfcTagListe = new NfcTagListe(aktJob.getId());
    }
    long tagIDNumber = 0;
    // Tag ID aus den übertragenen Daten lesen
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

    // aus dem Byte Array der ID die Dezimalzahl bilden
    if (tag != null) {
    byte[] tagID = tag.getId();
    long faktor = 1;
    for (byte b : tagID) {
    tagIDNumber += Byte.toUnsignedInt(b) * faktor;
    faktor *= 256L;
    }
    }
    }*/

    // Rückrufhandler

    /**
     * Rückruf aus der Monats- oder Wochenansicht zum öffnen eines bestimmten Tages
     *
     * @param datum Datum des Tages, der geöffnet werden soll
     */
    @Override
    public void onEditArbeitstag(Datum datum) {
        OpenView(VIEW_TAG, datum.getTimeInMillis());
    }

    /**
     * Rückruf vom arbeitstag zum Wechsel in den Monat oder die Woche
     *
     * @param ansicht Welche Ansicht soll geöffnet werden Woche => ISetup.VIEW_WOCHE; Monat => ISetup.VIEW_MONAT
     * @param datum   Datum des ersten Tages der Periode, die geöffnet werden soll
     */
    @Override
    public void onArbeitstagGoback(int ansicht, Datum datum) {
        OpenView(ansicht, datum.getTimeInMillis());
    }

    @Override
    public void onArbeitswocheGoMonat(Datum datum) {
        OpenView(ISettings.VIEW_MONAT, datum.getTimeInMillis());
    }
}
