org.digitalcampus.oppia.activity.CourseIndexActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.digitalcampus.oppia.activity.CourseIndexActivity.java

Source

/* 
 * This file is part of OppiaMobile - https://digital-campus.org/
 * 
 * OppiaMobile 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.
 * 
 * OppiaMobile 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 OppiaMobile. If not, see <http://www.gnu.org/licenses/>.
 */

package org.digitalcampus.oppia.activity;

import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Callable;

import org.opendeliver.oppia.R;
import org.digitalcampus.oppia.adapter.SectionListAdapter;
import org.digitalcampus.oppia.application.MobileLearning;
import org.digitalcampus.oppia.exception.InvalidXMLException;
import org.digitalcampus.oppia.model.Activity;
import org.digitalcampus.oppia.model.CompleteCourse;
import org.digitalcampus.oppia.model.CompleteCourseProvider;
import org.digitalcampus.oppia.model.Course;
import org.digitalcampus.oppia.model.CourseMetaPage;
import org.digitalcampus.oppia.model.Lang;
import org.digitalcampus.oppia.model.Section;
import org.digitalcampus.oppia.service.TrackerService;
import org.digitalcampus.oppia.task.ParseCourseXMLTask;
import org.digitalcampus.oppia.utils.ImageUtils;
import org.digitalcampus.oppia.utils.UIUtils;
import org.digitalcampus.oppia.utils.xmlreaders.CourseXMLReader;

import android.animation.ValueAnimator;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import javax.inject.Inject;

public class CourseIndexActivity extends AppActivity
        implements OnSharedPreferenceChangeListener, ParseCourseXMLTask.OnParseXmlListener {

    public static final String TAG = CourseIndexActivity.class.getSimpleName();
    public static final String JUMPTO_TAG = "JumpTo";
    public static final int RESULT_JUMPTO = 99;

    private Course course;
    private CompleteCourse parsedCourse;
    private ArrayList<Section> sections;
    private SharedPreferences prefs;
    private Activity baselineActivity;
    private AlertDialog aDialog;
    private View loadingCourseView;
    private SectionListAdapter sla;

    private String digestJumpTo;

    @Inject
    CompleteCourseProvider completeCourseProvider;

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

        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        prefs.registerOnSharedPreferenceChangeListener(this);
        loadingCourseView = findViewById(R.id.loading_course);

        /*
        ----- CollapsingToolbar layout
        FloatingActionButton myFab = (FloatingActionButton)  findViewById(R.id.scorecard_fab);
        if (myFab != null) {
        myFab.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent i = new Intent(CourseIndexActivity.this, ScorecardActivity.class);
                Bundle tb = new Bundle();
                tb.putSerializable(Course.TAG, course);
                i.putExtras(tb);
                startActivityForResult(i, 1);
            }
        });
        }*/

        Bundle bundle = this.getIntent().getExtras();
        if (bundle != null) {
            course = (Course) bundle.getSerializable(Course.TAG);

            String digest = (String) bundle.getSerializable(JUMPTO_TAG);
            if (digest != null) {
                //If there is a digest, we have to parse the course synchronously to avoid showing this activity
                parsedCourse = completeCourseProvider.getCompleteCourseSync(this, course);

                //We also check first if the baseline is completed before jumping to digest
                boolean baselineCompleted = isBaselineCompleted();
                if (baselineCompleted) {
                    course.setMetaPages(parsedCourse.getMetaPages());
                    sections = parsedCourse.getSections();
                    startCourseActivityByDigest(digest);
                    initializeCourseIndex(false);
                } else {
                    sections = parsedCourse.getSections();
                    initializeCourseIndex(false);
                    showBaselineMessage(digest);
                }
            } else {
                completeCourseProvider.getCompleteCourseAsync(this, course);
            }
        }

    }

    private void initializeDagger() {
        MobileLearning app = (MobileLearning) getApplication();
        app.getComponent().inject(this);
    }

    @Override
    public void onStart() {
        super.onStart();
        // set image
        if (course.getImageFile() != null) {
            BitmapDrawable bm = ImageUtils.LoadBMPsdcard(course.getImageFileFromRoot(), this.getResources(),
                    R.drawable.opendeliver_logo);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (aDialog != null) {
            aDialog.show();
        }

        if (digestJumpTo != null && isBaselineCompleted()) {
            startCourseActivityByDigest(digestJumpTo);
            digestJumpTo = null;
            return;
        }

        // start a new tracker service
        Intent service = new Intent(this, TrackerService.class);

        Bundle tb = new Bundle();
        tb.putBoolean("backgroundData", true);
        service.putExtras(tb);
        this.startService(service);

        // remove any saved state info from shared prefs in case they interfere with subsequent page views
        Editor editor = prefs.edit();
        Map<String, ?> keys = prefs.getAll();

        for (Map.Entry<String, ?> entry : keys.entrySet()) {
            if (entry.getKey().startsWith("widget_")) {
                editor.remove(entry.getKey());
            }
        }
        editor.apply();

        if ((parsedCourse != null) && (sections != null) && (sections.size() > 0)) {
            parsedCourse.setCourseId(course.getCourseId());
            parsedCourse.updateCourseActivity(this);
            sla.notifyDataSetChanged();
            if (!isBaselineCompleted()) {
                showBaselineMessage(null);
            }
        }
    }

    @Override
    public void onPause() {
        if (aDialog != null) {
            aDialog.dismiss();
            aDialog = null;
        }
        super.onPause();
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.clear();
        getMenuInflater().inflate(R.menu.activity_course_index, menu);
        ArrayList<CourseMetaPage> ammp = course.getMetaPages();
        int order = 104;
        for (CourseMetaPage mmp : ammp) {
            Lang titleLang = mmp
                    .getLang(prefs.getString(PrefsActivity.PREF_LANGUAGE, Locale.getDefault().getLanguage()));

            if (titleLang != null) {
                String title = titleLang.getContent();
                menu.add(0, mmp.getId(), order, title).setIcon(android.R.drawable.ic_menu_info_details);
                order++;
            }

        }
        UIUtils.showUserData(menu, this, course);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int itemId = item.getItemId();
        if (itemId == R.id.menu_language) {
            createLanguageDialog();
            return true;
        } else if (itemId == android.R.id.home) {
            this.finish();
            return true;
        } else {
            Intent i;
            Bundle tb = new Bundle();

            if (itemId == R.id.menu_help) {
                i = new Intent(this, AboutActivity.class);
                tb.putSerializable(AboutActivity.TAB_ACTIVE, AboutActivity.TAB_HELP);
            } else if (itemId == R.id.menu_scorecard) {
                i = new Intent(this, ScorecardActivity.class);
                tb.putSerializable(Course.TAG, course);
            } else {
                i = new Intent(this, CourseMetaPageActivity.class);
                tb.putSerializable(Course.TAG, course);
                tb.putInt(CourseMetaPage.TAG, item.getItemId());
            }
            i.putExtras(tb);
            startActivityForResult(i, 1);
            return true;
        }
    }

    private void createLanguageDialog() {
        UIUtils.createLanguageDialog(this, course.getMultiLangInfo().getLangs(), prefs, new Callable<Boolean>() {
            public Boolean call() throws Exception {
                CourseIndexActivity.this.onStart();
                return true;
            }
        });
    }

    private void initializeCourseIndex(boolean animate) {

        final ListView listView = (ListView) findViewById(R.id.section_list);
        if (listView == null)
            return;
        ViewCompat.setNestedScrollingEnabled(listView, true);
        sla = new SectionListAdapter(CourseIndexActivity.this, course, sections,
                new SectionListAdapter.CourseClickListener() {
                    @Override
                    public void onActivityClicked(String activityDigest) {
                        startCourseActivityByDigest(activityDigest);
                    }
                });

        if (animate) {
            AlphaAnimation fadeOutAnimation = new AlphaAnimation(1f, 0f);
            fadeOutAnimation.setDuration(700);
            fadeOutAnimation.setFillAfter(true);

            listView.setAlpha(0f);
            ValueAnimator animator = ValueAnimator.ofFloat(1f, 0f);
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    listView.setTranslationX((Float) valueAnimator.getAnimatedValue() * 80);
                    listView.setAlpha(1f - (Float) valueAnimator.getAnimatedValue());
                }
            });
            animator.setDuration(700);
            animator.start();
            loadingCourseView.startAnimation(fadeOutAnimation);

        } else {
            loadingCourseView.setVisibility(View.GONE);
            listView.setVisibility(View.VISIBLE);
        }

        listView.setAdapter(sla);
    }

    private boolean isBaselineCompleted() {
        ArrayList<Activity> baselineActs = parsedCourse.getBaselineActivities();
        // TODO how to handle if more than one baseline activity
        for (Activity a : baselineActs) {
            if (!a.isAttempted()) {
                this.baselineActivity = a;
                return false;
            }
        }
        return true;
    }

    private void showBaselineMessage(final String digest) {
        aDialog = new AlertDialog.Builder(this, R.style.Oppia_AlertDialogStyle).create();
        aDialog.setCancelable(false);
        aDialog.setTitle(R.string.alert_pretest);
        aDialog.setMessage(this.getString(R.string.alert_pretest_summary));

        aDialog.setButton(DialogInterface.BUTTON_NEGATIVE, this.getString(R.string.open),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        //We set the digest to be able to jump to this activity after passing the baseline
                        digestJumpTo = digest;

                        Intent intent = new Intent(CourseIndexActivity.this, CourseActivity.class);
                        Bundle tb = new Bundle();
                        Section section = new Section();
                        section.addActivity(CourseIndexActivity.this.baselineActivity);
                        tb.putSerializable(Section.TAG, section);
                        tb.putSerializable(CourseActivity.BASELINE_TAG, true);
                        tb.putSerializable(SectionListAdapter.TAG_PLACEHOLDER, 0);
                        tb.putSerializable(Course.TAG, CourseIndexActivity.this.course);
                        intent.putExtras(tb);
                        startActivity(intent);
                    }
                });
        aDialog.setButton(DialogInterface.BUTTON_POSITIVE, this.getString(R.string.cancel),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        CourseIndexActivity.this.finish();
                    }
                });
        aDialog.show();
    }

    private void startCourseActivityByDigest(String digest) {

        boolean allSectionsCompleted = true;
        for (Section section : sections) {
            boolean allActivitiesCompleted = true;
            for (int i = 0; i < section.getActivities().size(); i++) {
                Activity act = section.getActivities().get(i);

                if (act.getDigest().equals(digest)) {
                    if ((course.getSequencingMode().equals(Course.SEQUENCING_MODE_COURSE))
                            && (!allSectionsCompleted || !allActivitiesCompleted)) {
                        UIUtils.showAlert(this, R.string.sequencing_dialog_title,
                                R.string.sequencing_course_message);
                    } else if ((course.getSequencingMode().equals(Course.SEQUENCING_MODE_SECTION))
                            && (!allActivitiesCompleted)) {
                        UIUtils.showAlert(this, R.string.sequencing_dialog_title,
                                R.string.sequencing_section_message);
                    } else {
                        Intent intent = new Intent(this, CourseActivity.class);
                        Bundle tb = new Bundle();
                        tb.putSerializable(Section.TAG, section);
                        tb.putSerializable(Course.TAG, course);
                        tb.putSerializable(SectionListAdapter.TAG_PLACEHOLDER, i);
                        intent.putExtras(tb);
                        startActivity(intent);
                    }
                    //When we find the activity we are looking for, we can stop the search
                    return;
                } else {
                    //If is not the activity we are searching for, we check if it's completed
                    //(for sequencing purposes)
                    allActivitiesCompleted = allActivitiesCompleted && act.getCompleted();
                }
            }
            allSectionsCompleted = allSectionsCompleted && allActivitiesCompleted;
        }
    }

    private void showErrorMessage() {
        UIUtils.showAlert(CourseIndexActivity.this, R.string.error, R.string.error_reading_xml,
                new Callable<Boolean>() {
                    public Boolean call() throws Exception {
                        CourseIndexActivity.this.finish();
                        return true;
                    }
                });
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        // update the points/badges by invalidating the menu
        if (key.equalsIgnoreCase(PrefsActivity.PREF_TRIGGER_POINTS_REFRESH)) {
            supportInvalidateOptionsMenu();
        }
    }

    //@Override
    public void onParseComplete(CompleteCourse parsed) {
        parsedCourse = parsed;
        course.setMetaPages(parsedCourse.getMetaPages());
        sections = parsedCourse.getSections();

        boolean baselineCompleted = isBaselineCompleted();
        if (!baselineCompleted) {
            showBaselineMessage(null);
        }
        initializeCourseIndex(true);
    }

    //@Override
    public void onParseError() {
        showErrorMessage();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            if (resultCode == RESULT_JUMPTO) {
                String digest = data.getStringExtra(JUMPTO_TAG);
                startCourseActivityByDigest(digest);
            }
        }
    }
}