Proyectos de Subversion Android Microlearning

Rev

Rev 43 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

package com.cesams.twogetskills.activity;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.view.GravityCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.net.ConnectivityManager;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;


import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.bumptech.glide.request.RequestOptions;
import com.cesams.twogetskills.Configuration;
import com.cesams.twogetskills.dao.AnswerDao;
import com.cesams.twogetskills.dao.AppDatabase;
import com.cesams.twogetskills.dao.CapsuleDao;
import com.cesams.twogetskills.dao.CompanyDao;
import com.cesams.twogetskills.dao.DatabaseHelper;
import com.cesams.twogetskills.dao.ProgressDao;
import com.cesams.twogetskills.dao.QuestionDao;
import com.cesams.twogetskills.dao.QuizDao;
import com.cesams.twogetskills.dao.SlideDao;
import com.cesams.twogetskills.dao.SyncDao;
import com.cesams.twogetskills.dao.TopicDao;
import com.cesams.twogetskills.dao.UserExtendedDao;
import com.cesams.twogetskills.dao.UserLogDao;
import com.cesams.twogetskills.entity.UserExtended;
import com.cesams.twogetskills.fragment.CapsuleFragment;
import com.cesams.twogetskills.fragment.CompanyFragment;
import com.cesams.twogetskills.fragment.FinishCapsuleFragment;
import com.cesams.twogetskills.fragment.FinishTopicFragment;
import com.cesams.twogetskills.fragment.GalleryFragment;
import com.cesams.twogetskills.fragment.ProgressFragment;
import com.cesams.twogetskills.fragment.SlideFragment;
import com.cesams.twogetskills.fragment.TimelineFragment;
import com.cesams.twogetskills.fragment.TopicFragment;
import com.cesams.twogetskills.fragment.UserProfileFragment;
import com.cesams.twogetskills.library.Http;
import com.cesams.twogetskills.library.MD5;
import com.cesams.twogetskills.library.UniqueID;
import com.cesams.twogetskills.entity.Answer;
import com.cesams.twogetskills.entity.Capsule;
import com.cesams.twogetskills.entity.Company;
import com.cesams.twogetskills.entity.Progress;
import com.cesams.twogetskills.entity.Question;
import com.cesams.twogetskills.entity.Quiz;
import com.cesams.twogetskills.entity.Slide;
import com.cesams.twogetskills.entity.Sync;
import com.cesams.twogetskills.entity.Topic;
import com.cesams.twogetskills.entity.UserLog;
import com.cesams.twogetskills.preference.Preference;
import com.cesams.twogetskills.receiver.ConnectivityReceiver;
import com.cesams.twogetskills.receiver.InternalReceiver;
import com.cesams.twogetskills.room.ResultCount;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;

import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider;
import androidx.room.Database;

import com.cesams.twogetskills.Constants;
import com.cesams.twogetskills.R;

import com.cesams.twogetskills.fragment.IntroFragment;
import com.cesams.twogetskills.fragment.SigninFragment;
import com.cesams.twogetskills.skeleton.ITwoGetSkills;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TimeZone;

//import de.hdodenhof.circleimageview.CircleImageView;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends  AppCompatActivity implements ITwoGetSkills,NavigationView.OnNavigationItemSelectedListener {
    private boolean isSyncDevice = false;
    private boolean isSyncToken = false;
    private boolean isSyncBatch = false;
    private boolean isForeground = false;
    private boolean isSmartLockLoginRun = false;

    private final static String PREFIX_FRAG = "FRAG";
    private final static String TAG = "C2GS - MainActivity";

    private DrawerLayout mDrawer;
    private ActionBarDrawerToggle mDrawerToggle;

    private HashMap<String, Fragment> fragmentHashMap;

    private ImageView navHeaderUserImage;

    private TextView navHeaderUserName;
    private TextView navHeaderUserEmail;
    private TextView textViewMessageNotConnection;



    private Preference preference;
    private boolean connected = false;
    private ConnectivityReceiver mConnectivityReceiver;
    private InternalReceiver mInternalReceiver;
    private ProgressBar mProgressBar;

    private Account mAccount;
    private AppDatabase mAppDatabase;

    ActivityResultLauncher<Intent> mLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if(result.getResultCode() == RESULT_OK) {
                    boolean completed = result.getData().hasExtra("completed") && result.getData().getBooleanExtra("completed", false);
                    int requestCode = result.getData().hasExtra("requestCode") ? result.getData().getIntExtra("requestCode", 0) : 0;
                    if(requestCode == Constants.REQUEST_CODE_QUIZ) {
                        createProgressAndSyncRecord(preference.getSlideUuidActive(), completed, true, false);
                    } else  if(requestCode == Constants.REQUEST_CODE_AUDIO_VIDEO) {
                        createProgressAndSyncRecord(preference.getSlideUuidActive(), completed, false, true);
                    } else {
                        createProgressAndSyncRecord(preference.getSlideUuidActive(), completed, false, false);
                    }
                }
            }
    );


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

        Log.d(TAG, "MainActivity onCreate");

        /**** CANAL DE NOTIFICACIONES **/
        createNotificationChannel();

        /*** CUENTAS DE SINCRONIZACION **/
        mAccount =  CreateSyncAccount(getApplicationContext());


        // Get the content resolver for your app
        //mResolver = getContentResolver();

        mAppDatabase = DatabaseHelper.getInstance(getApplicationContext()).getAppDatabase();

        preference = Preference.getInstance(getApplicationContext());

        Log.d("BUG 2PLANO", "MainActivity - onCreate");
        preference.load();

        if(TextUtils.isEmpty(preference.getDeviceUuid())) {
            String uuid = UniqueID.id(getApplicationContext());
            preference.setDeviceUuid(uuid);
            preference.save();

            Sync sync = new Sync(Constants.SYNC_ADAPTER_TYPE_DEVICE, uuid);
            mAppDatabase.getSyncDao().insert(sync);

            if(!TextUtils.isEmpty(preference.getDeviceToken())) {
                sync = new Sync(Constants.SYNC_ADAPTER_TYPE_FCM, preference.getDeviceToken());
                mAppDatabase.getSyncDao().insert(sync);
            }
        }

        fragmentHashMap = new HashMap<>();

        mProgressBar = findViewById(R.id.progressBar);
        Toolbar mToolbar = findViewById(R.id.toolbar);
        setSupportActionBar((Toolbar) findViewById(R.id.toolbar));

        mDrawer = findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(
                this, mDrawer, mToolbar, R.string.navigation_drawer_open,
                R.string.navigation_drawer_close);

        mDrawerToggle.setToolbarNavigationClickListener(v -> onBackPressed());

        mDrawer.addDrawerListener(mDrawerToggle);
        mDrawerToggle.syncState();

        NavigationView navigationView = findViewById(R.id.navigation_view);
        navigationView.setNavigationItemSelectedListener(this);

        View header = navigationView.getHeaderView(0);
        //navHeaderUserImage = (CircleImageView) header.findViewById(R.id.nav_header_user_image);
        navHeaderUserImage = header.findViewById(R.id.nav_header_user_image);
        navHeaderUserName = header.findViewById(R.id.nav_header_user_name);
        navHeaderUserEmail =  header.findViewById(R.id.nav_header_user_email);

        textViewMessageNotConnection = findViewById(R.id.main_activity_text_view_message_not_connection);

        mConnectivityReceiver = new ConnectivityReceiver();
        registerReceiver(mConnectivityReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

        IntentFilter intentFilterInternal = new IntentFilter();
        intentFilterInternal.addAction(Constants.BROADCAST_TYPE_NOTIFICATION);
        intentFilterInternal.addAction(Constants.BROADCAST_TYPE_TOKEN);
        intentFilterInternal.addAction(Constants.BROADCAST_TYPE_COMMAND);
        intentFilterInternal.addAction(Constants.BROADCAST_TYPE_SYNC_TO_SERVER_OR_CHECK_CHANGES);

        mInternalReceiver = new InternalReceiver();
        registerReceiver(mInternalReceiver, intentFilterInternal);

    }

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

        try  {
            unregisterReceiver(mConnectivityReceiver);
            unregisterReceiver(mInternalReceiver);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onResume() {
        super.onResume();
        isForeground = true;

        Log.d("BUG 2PLANO", "MainActivity - onCreate");
        preference = Preference.getInstance(getApplicationContext());
        preference.load();
        
        reloadNavHeader();

        Log.e("Se ejecuta", "On resumen");

        if(TextUtils.isEmpty(preference.getUserUuid())) {

            //Verifico que el teclado no vaya a relanzar el fragment de intro al usar Google Smartlock para traer
            //Informacion de inicio de sesion almacenada en su cuenta personal de Google
            if (!isSmartLockLoginRun) {
                invokeFragment(Constants.IDX_FRAGMENT_INTRO);
                isSmartLockLoginRun= true;
            }


        } else {
            if(preference.getFragmentIdxActive() == 0) {
                invokeFragment(Constants.IDX_FRAGMENT_TOPICS);
            } else {
                invokeFragment(preference.getFragmentIdxActive());
            }
        }

    }

    @Override
    protected void onPause() {
        super.onPause();

        isForeground = false;
        preference.save();
    }

    /*
    @Override
    protected void onRestart() {
        super.onRestart();
        preference = Preference.getInstance(getApplicationContext());
        preference.load();

        if(TextUtils.isEmpty(preference.getUserUuid())) {

            //Verifico que el teclado no vaya a relanzar el fragment de intro al usar Google Smartlock para traer
            //Informacion de inicio de sesion almacenada en su cuenta personal de Google
            if (!isSmartLockLoginRun) {
                invokeFragment(Constants.IDX_FRAGMENT_INTRO);
                isSmartLockLoginRun= true;
            }


        } else {
            if(preference.getFragmentIdxActive() == 0) {
                invokeFragment(Constants.IDX_FRAGMENT_TOPICS);
            } else {
                invokeFragment(preference.getFragmentIdxActive());
            }
        }


    }
    */

    /*
    @Override
    protected void onStop() {
        super.onStop();
        preference.save();

    }
    */

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        int title;
        mDrawer.closeDrawers();

        switch (menuItem.getItemId()) {
            case R.id.nav_topics :
                setTitleActionBar(getString(R.string.menu_topics));
                invokeFragment(Constants.IDX_FRAGMENT_TOPICS);
                break;
            case R.id.nav_timeline:
                setTitleActionBar(getString(R.string.menu_timeline));
                invokeFragment(Constants.IDX_FRAGMENT_TIMELINE);

                break;
            case R.id.nav_progress:

                if(preference.getCompanyCount() > 1) {
                    invokeFragment(Constants.IDX_FRAGMENT_COMPANIES);
                }  else {
                    setTitleActionBar(getString(R.string.menu_progress));
                    invokeFragment(Constants.IDX_FRAGMENT_PROGRESS);
                }
                break;

            case R.id.nav_userprofile:
                setTitleActionBar(getString(R.string.menu_user_profile));
                invokeFragment(Constants.IDX_FRAGMENT_USER_PROFILE);
                break;

            case R.id.nav_exit_app:
                setTitleActionBar(getString(R.string.menu_exit));
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setTitle(R.string.alter_dialog_close_app_title);
                builder.setMessage(R.string.alter_dialog_close_app_message);
                builder.setNegativeButton(R.string.alter_dialog_button_no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
                builder.setPositiveButton(R.string.alter_dialog_button_yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        signout();
                    }
                });

                AlertDialog dialog = builder.create();
                dialog.show();

                break;

            default:
                throw new IllegalArgumentException("menu option not implemented!!");
        }

        mDrawer.closeDrawer(GravityCompat.START);

        return true;
    }

    private void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(Constants.NOTIFICATION_CHANNEL_ID, name, importance);
        channel.setDescription(description);
        channel.setShowBadge(true);


        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }


    @Override
    public void showFcmNotification(String title, String body, int new_capsules)
    {

        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(MainActivity.this, Constants.NOTIFICATION_CHANNEL_ID)
                        .setSmallIcon(R.drawable.ic_notificacion) //set icon for notification
                        .setContentTitle(title) //set title of notification
                        .setContentText(body)//this is notification message
                        .setAutoCancel(true) // makes auto cancel of notification
                        .setPriority(NotificationCompat.PRIORITY_DEFAULT); //set priority of notification

        if(new_capsules > 0) {
            builder.setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE);
            builder.setNumber(new_capsules);
        }

        Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        //notification message will get at NotificationView
        notificationIntent.putExtra(title, body);

        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent,
                PendingIntent.FLAG_IMMUTABLE);
        builder.setContentIntent(pendingIntent);

        // Add as notification
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(0, builder.build());


        if(new_capsules > 0) {

            String message = new_capsules == 1
                    ? "Hay 1 cápsula nueva disponible"
                    : "Hay " + new_capsules + " cápsulas disponible";

            showMessageSnackBarWithClose(message);
        } else {
            showMessageSnackBarWithClose(body);
        }


    }

    @Override
    public void signout()
    {
        mAppDatabase.getAnswerDao().removeAll();
        mAppDatabase.getQuestionDao().removeAll();
        mAppDatabase.getQuizDao().removeAll();
        mAppDatabase.getSlideDao().removeAll();
        mAppDatabase.getCapsuleDao().removeAll();
        mAppDatabase.getTopicDao().removeAll();
        mAppDatabase.getUserExtendedDao().removeAll();


        mAppDatabase.getUserLogDao().removeAll();
        mAppDatabase.getProgressDao().removeAll();

        preference.setUserUuid("");
        preference.setFirstName("");
        preference.setLastName("");
        preference.setEmail("");
        preference.setImage("");
        preference.setMaxDateChanges("");
        preference.setCompanyCount(0);
        preference.setCompanyUuidActive("");
        preference.setTopicUuidActive("");
        preference.setCapsuleUuidActive("");
        preference.setSlideUuidActive("");
        preference.save();

        invokeFragment(Constants.IDX_FRAGMENT_INTRO);
    }

    @Override
    public void onBackPressed() {

        //super.onBackPressed();
        switch (preference.getFragmentIdxActive())
        {

/*
            case Constants.IDX_FRAGMENT_INTRO :
            case Constants.IDX_FRAGMENT_SIGNIN  :
            case Constants.IDX_FRAGMENT_TOPICS  :
                finish();
                return;*/

            case Constants.IDX_FRAGMENT_PROGRESS :
               if(preference.getCompanyCount() > 1) {
                   invokeFragment(Constants.IDX_FRAGMENT_COMPANIES);
               } else {
                   invokeFragment(Constants.IDX_FRAGMENT_TOPICS);
               }
               break;

            case Constants.IDX_FRAGMENT_COMPANIES:
            case Constants.IDX_FRAGMENT_TIMELINE  :
            case Constants.IDX_FRAGMENT_CAPSULES :
            case Constants.IDX_FRAGMENT_FINISH_TOPIC :

                preference.setTopicUuidActive("");
                preference.setCapsuleUuidActive("");
                preference.setSlideUuidActive("");
                preference.save();

                invokeFragment(Constants.IDX_FRAGMENT_TOPICS);
                return;

            case Constants.IDX_FRAGMENT_SLIDES :
                invokeFragment(Constants.IDX_FRAGMENT_CAPSULES);
                return;

            case Constants.IDX_FRAGMENT_GALLERY :
                invokeFragment(Constants.IDX_FRAGMENT_SLIDES);
                return;

            case Constants.IDX_FRAGMENT_FINISH_CAPSULE :
                preference.setCapsuleUuidActive("");
                preference.setSlideUuidActive("");
                preference.save();

                invokeFragment(Constants.IDX_FRAGMENT_CAPSULES);
                return;

        }
    }



    @Override
    public void hideProgressBar() {

        //accessing it from ui-thread
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mProgressBar.setVisibility(View.INVISIBLE);
            }
        });

    }

    @Override
    public void showProgressBar() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mProgressBar.setVisibility(View.VISIBLE);
            }
        });


    }





    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.drawer, menu);
        return true;
    }




      /**
         * Create a new dummy account for the sync adapter
         *
         * @param context The application context
         */
    public static Account CreateSyncAccount(Context context) {
        // Create the account type and default account
        Account newAccount = new Account(
                Constants.ACCOUNT, Constants.ACCOUNT_TYPE);
        // Get an instance of the Android account manager
        AccountManager accountManager =
                (AccountManager) context.getSystemService(
                        ACCOUNT_SERVICE);
        /*
         * Add the account and account type, no password or user data
         * If successful, return the Account object, otherwise report an error.
         */
        if (accountManager.addAccountExplicitly(newAccount, null, null)) {
            /*
             * If you don't set android:syncable="true" in
             * in your <provider> element in the manifest,
             * then call context.setIsSyncable(account, AUTHORITY, 1)
             * here.
             */

            ContentResolver.setIsSyncable(newAccount, Constants.AUTHORITY, 1);
            ContentResolver.setSyncAutomatically(newAccount, Constants.AUTHORITY, true);
            ContentResolver.addPeriodicSync(newAccount,
                    Constants.AUTHORITY,  Bundle.EMPTY, Constants.SYNC_INTERVAL);


        } else {
            /*
             * The account exists or some other error occurred. Log this, report it,
             * or handle it internally.
             */

            Account[] accounts = accountManager.getAccounts();
            if(accounts != null && accounts.length > 0) {

                for(Account account : accounts)
                {
                    if(account.type.equals(Constants.ACCOUNT_TYPE)) {
                        return account;
                    }
                }
                return accounts[0];
            } else {
                return null;
            }



        }

        return newAccount;


    }





    @Override
    public void createSyncRecordNewToken(String token)
    {

        preference.setDeviceToken (token);
        preference.save();

        if(!TextUtils.isEmpty(preference.getDeviceUuid())) {
            Sync sync = new Sync(Constants.SYNC_ADAPTER_TYPE_FCM, token);
            mAppDatabase.getSyncDao().insert(sync);
        }
    }




    @Override
    public void executeFcmCommand(String command)
    {

        if (command.equals("signout")) {
            signout();
        }
    }



    @Override
    public void setConnectedInternet(Boolean isConnected)
    {
        connected = isConnected;
        textViewMessageNotConnection.setVisibility(isConnected ? View.INVISIBLE : View.VISIBLE);
    }

    @Override
    public boolean isConnectedInternet() {
        return connected;
    }

    @Override
    public void showMessageSnackBar(String message) {
        Snackbar.make(this.findViewById(R.id.fragment_container), message, Snackbar.LENGTH_LONG).show();
    }


    @Override
    public void showMessageSnackBarWithClose(String message) {
        final Snackbar snackBar = Snackbar.make(this.findViewById(R.id.fragment_container), message, Snackbar.LENGTH_INDEFINITE);

        snackBar.setAction(R.string.snackbar_close, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Call your action method here
                snackBar.dismiss();
            }
        });
        snackBar.show();


    }

    @Override
    public void onErrorFatal() {


        invokeFragment(Constants.IDX_FRAGMENT_SIGNIN);
    }

    @Override
    public void invokeFragment(int fragmentIdxActiveNuevo)
    {
        String fragmentKeyActual    = PREFIX_FRAG + preference.getFragmentIdxActive();
        String fragmentKeyNuevo         = PREFIX_FRAG + fragmentIdxActiveNuevo;
        preference.setFragmentIdxActive(fragmentIdxActiveNuevo);
        preference.save();

        Fragment fragment;
        if(!fragmentKeyActual.equalsIgnoreCase(fragmentKeyNuevo)) {
            if(fragmentHashMap.containsKey(fragmentKeyActual)) {
                fragment = fragmentHashMap.get(fragmentKeyActual);
                if(fragment != null) {
                    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                    fragmentTransaction.hide(fragment);
                    fragmentTransaction.commitAllowingStateLoss();
                }
            }
        }

        boolean add = false;
        fragment = null;
        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        mDrawerToggle.setDrawerIndicatorEnabled(false);


        switch(fragmentIdxActiveNuevo) {
            case Constants.IDX_FRAGMENT_SIGNIN :
                getSupportActionBar().hide();
                 if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                     fragment = fragmentHashMap.get(fragmentKeyNuevo);
                 } else {
                     add = true;
                     fragment = new SigninFragment();
                 }
                break;

            case Constants.IDX_FRAGMENT_TOPICS :


                getSupportActionBar().show();
                mDrawerToggle.setDrawerIndicatorEnabled(true);
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new TopicFragment();
                }
                break;


            case Constants.IDX_FRAGMENT_CAPSULES :
                getSupportActionBar().show();
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new CapsuleFragment();
                }
                break;

            case Constants.IDX_FRAGMENT_SLIDES :
                getSupportActionBar().show();
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new SlideFragment();
                }
                break;

            case Constants.IDX_FRAGMENT_GALLERY :
                getSupportActionBar().show();
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new GalleryFragment();
                }

                break;

            case Constants.IDX_FRAGMENT_FINISH_CAPSULE :
                getSupportActionBar().hide();
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new FinishCapsuleFragment();
                }
                break;

            case Constants.IDX_FRAGMENT_FINISH_TOPIC :
                getSupportActionBar().hide();
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new FinishTopicFragment();
                }
                break;

            case Constants.IDX_FRAGMENT_TIMELINE :
                getSupportActionBar().show();
                mDrawerToggle.setDrawerIndicatorEnabled(true);
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new TimelineFragment();
                }
                break;

            case Constants.IDX_FRAGMENT_COMPANIES:
                getSupportActionBar().show();
                mDrawerToggle.setDrawerIndicatorEnabled(true);
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new CompanyFragment();
                }
                break;

            case Constants.IDX_FRAGMENT_PROGRESS :
                getSupportActionBar().show();
                mDrawerToggle.setDrawerIndicatorEnabled(true);
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new ProgressFragment();
                }
                break;

            case Constants.IDX_FRAGMENT_USER_PROFILE:
                getSupportActionBar().show();
                mDrawerToggle.setDrawerIndicatorEnabled(true);
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new UserProfileFragment();
                }
                break;

            default :
                getSupportActionBar().hide();
                if(fragmentHashMap.containsKey(fragmentKeyNuevo)) {
                    fragment = fragmentHashMap.get(fragmentKeyNuevo);
                } else {
                    add = true;
                    fragment = new IntroFragment();
                }
                break;


        }

        if(add) {
            fragmentHashMap.put(fragmentKeyNuevo, fragment);

            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.add(R.id.fragment_container, fragment, fragmentKeyNuevo);
            fragmentTransaction.commitAllowingStateLoss();
        }


        if(fragment != null) {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.show(fragment);
            fragmentTransaction.commitAllowingStateLoss();
        }

    }

    @Override
    public void changeTopicActive(String topicUuid)
    {
        Log.d(TAG, "changeTopicActive : " + topicUuid);
       // Log.e("Guardo", "Topico en Main");

        preference.setTopicUuidActive(topicUuid);
        preference.setCapsuleUuidActive("");
        preference.setSlideUuidActive("");
        preference.save();

        invokeFragment(Constants.IDX_FRAGMENT_CAPSULES);
    }

    @Override
    public void changeCapsuleActive(String capsuleUuid)
    {
        Log.d(TAG, "changeCapsuleActive : " + capsuleUuid);



        preference.setCapsuleUuidActive(capsuleUuid);
        preference.setSlideUuidActive("");
        preference.save();

        invokeFragment(Constants.IDX_FRAGMENT_SLIDES);
    }

    @Override
    public void changeCompanyActive(String companyUuid)
    {
        Log.d(TAG, "changeCompanyActive : " + companyUuid);

        preference.setCompanyUuidActive(companyUuid);
        preference.save();
    }

    @Override
    public synchronized void changeSlideActive(String slideUuid, String type, boolean showGallery)
    {

        Log.d(TAG, "changeSlideActive : " + slideUuid);

        if(!preference.getSlideUuidActive().equals(slideUuid) && type.equals(Constants.SLIDE_TYPE_IMAGE)) {
            Log.d(TAG, "registerOnPageChangeCallback - createProgressAndSyncRecord");

            createProgressAndSyncRecord(slideUuid, true, false, false);
        }
        preference.setSlideUuidActive(slideUuid);
        preference.save();


        if(showGallery) {
            invokeFragment(Constants.IDX_FRAGMENT_GALLERY);
        }
    }

    @Override
    public String getTopicUuidActive()
    {
        return preference.getTopicUuidActive();
    }

    @Override
    public String getCapsuleUuidActive()
    {
        return preference.getCapsuleUuidActive();
    }

    @Override
    public String getSlideUuidActive()
    {
        return preference.getSlideUuidActive();
    }

    @Override
    public String getCompanyUuidActive()
    {
        return preference.getCompanyUuidActive();
    }

    @Override
    public void setTitleActionBar(String title)
    {
        getSupportActionBar().setTitle(title);
    }

    @Override
    public synchronized void createProgressAndSyncRecord(String slideUuid, boolean completed, boolean isQuiz, boolean isAudioOrVideo)
    {
        Calendar calendar = Calendar.getInstance();
        Date date = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.FORMAT_DATETIME_SERVICE);
        String  dateOn = simpleDateFormat.format(date);

        SlideDao slideDao = mAppDatabase.getSlideDao();
        Slide slide =  slideDao.selectByUuid(slideUuid);

        CapsuleDao capsuleDao = mAppDatabase.getCapsuleDao();
        Capsule capsule = capsuleDao.selectByUuid(slide.getCapsuleUuid());

        TopicDao topicDao = mAppDatabase.getTopicDao();
        Topic topic = topicDao.selectByUuid(capsule.getTopicUuid());

        UserLog userLog;
        UserLogDao userLogDao = mAppDatabase.getUserLogDao();

        SyncDao syncDao = mAppDatabase.getSyncDao();
        Sync sync;

        String userUuid = preference.getUserUuid();

        // Progreso y UserLog  del Slide
        ProgressDao progressDao = mAppDatabase.getProgressDao();
        Progress progressSlide = progressDao.selectBySlideUuidAndUserUuid(slide.getUuid(), userUuid);
        Progress progressCapsule =  progressDao.selectByCapsuleUuidAndUserUuid(slide.getCapsuleUuid(),userUuid);
        Progress progressTopic =  progressDao.selectByTopicUuidAndUserUuid(slide.getTopicUuid(),userUuid);

        int totalSlides = 0;
        int viewSlides = 0;
        double percentaje = 0;
        boolean newRecord = false;
        boolean retakeQuiz = false;

        /*** INICIO PROCESO DIAPOSITIVA ***/
        if(progressSlide == null) {

            retakeQuiz = false;


            progressSlide = new Progress();
            progressSlide.setUserUuid(preference.getUserUuid());
            progressSlide.setCompanyUuid(topic.getCompanyUuid());
            progressSlide.setTopicUuid(topic.getUuid());
            progressSlide.setCapsuleUuid(capsule.getUuid());
            progressSlide.setSlideUuid(slide.getUuid());
            progressSlide.setType(Constants.PROGERSS_TYPE_SLIDE);
            progressSlide.setCompleted(completed ? 1 : 0);
            progressSlide.setAddedOn(dateOn);
            progressSlide.setUpdatedOn(dateOn);
            progressDao.insert(progressSlide);
        } else {
            retakeQuiz = true;

            if (progressSlide.getCompleted() == 1) {
                progressSlide.setReturningAfterCompleted(progressSlide.getReturningAfterCompleted() + 1);
            } else {
                if (completed) {
                    //0 y 1 para Boolean
                    progressSlide.setCompleted(completed  ? 1 : 0);
                } else {
                    progressSlide.setReturning(progressSlide.getReturning() + 1);
                }
            }

            progressSlide.setUpdatedOn(dateOn);
            progressDao.update(progressSlide);
        }



        /*** FIN PROCESO DIAPOSITIVA ***/



        /*** INICIO PROCESO TOPICO ***/
        ResultCount resultCount;


        resultCount = slideDao.getCountByTopicUuid(slide.getTopicUuid());
        totalSlides = resultCount.getCount();

        resultCount = progressDao.getCountSlidesCompletedByTopicUuidAndUserUuid(slide.getTopicUuid(), userUuid);
        viewSlides =  resultCount.getCount();
        if(totalSlides == 0) {
            percentaje = 0;
        } else {
            percentaje = (viewSlides * 100) / totalSlides;
        }
        
        if(progressTopic == null) {
            newRecord = true;
            progressTopic = new Progress();
            progressTopic.setUserUuid(preference.getUserUuid());
            progressTopic.setCompanyUuid( topic.getCompanyUuid());
            progressTopic.setTopicUuid (topic.getUuid());

            progressTopic.setViewSlides(viewSlides);
            progressTopic.setTotalSlides(totalSlides);
            progressTopic.setProgress (percentaje);
            progressTopic.setType(Constants.PROGERSS_TYPE_TOPIC);

            progressTopic.setAddedOn(dateOn);
            progressTopic.setUpdatedOn(dateOn);
             progressDao.insert(progressTopic);
        } else {
            newRecord = false;
            progressTopic.setViewSlides(viewSlides);
            progressTopic.setTotalSlides(totalSlides);
            progressTopic.setProgress (percentaje);
            progressDao.update(progressTopic);
        }

        try {
            JSONObject json = progressTopic.toJson();
            json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_PROGRESS);

            sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
            syncDao.insert(sync);
        } catch (JSONException e) {
        }

        if(newRecord) {
            userLog = new UserLog();
            userLog.setUserUuid(preference.getUserUuid());
            userLog.setActivity(Constants.USER_LOG_ACTIVITY_START_TOPIC);
            userLog.setCompanyUuid (topic.getCompanyUuid());
            userLog.setTopicUuid (topic.getUuid());
            userLog.setAddedOn(dateOn);


            userLogDao.insert(userLog);
            try {
                JSONObject json = userLog.toJson();
                json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_USER_LOG);

                sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
                syncDao.insert(sync);
            } catch (JSONException e) {
            }
        }
        /*** FIN PROCESO TOPICO ***/



        /*** INICIO PROCESO CAPSULA ***/
        resultCount = slideDao.getCountByCapsuleUuid(slide.getCapsuleUuid());
        totalSlides = resultCount.getCount();
        resultCount = progressDao.getCountSlidesCompletedByCapsuleUuidAndUserUuid(slide.getCapsuleUuid(), userUuid);
        viewSlides =  resultCount.getCount();
        if(totalSlides == 0) {
            percentaje = 0;
        } else {
            percentaje = (viewSlides * 100) / totalSlides;
        }

        if(progressCapsule == null) {
            newRecord = true;
            progressCapsule = new Progress();
            progressCapsule.setUserUuid(preference.getUserUuid());
            progressCapsule.setCompanyUuid(topic.getCompanyUuid());
            progressCapsule.setTopicUuid(topic.getUuid());
            progressCapsule.setCapsuleUuid (capsule.getUuid());
            progressCapsule.setViewSlides(viewSlides);
            progressCapsule.setTotalSlides(totalSlides);
            progressCapsule.setProgress(percentaje);
            progressCapsule.setType(Constants.PROGERSS_TYPE_CAPSULE);
            progressCapsule.setAddedOn(dateOn);
            progressCapsule.setUpdatedOn(dateOn);
            progressDao.insert(progressCapsule);

            Log.d(TAG, "Progress Capsule Nueva : setLastCapsuleActive : " + preference.getLastCapsuleUuidActive());
            preference.setLastCapsuleUuidActive(capsule.getUuid());
        } else {
            newRecord = false;
            progressCapsule.setViewSlides(viewSlides);
            progressCapsule.setTotalSlides(totalSlides);
            progressCapsule.setProgress(percentaje);

            Log.d(TAG, "Progress Capsule : getLastCapsuleActive : " + preference.getLastCapsuleUuidActive());
            Log.d(TAG, "Progress Capsule : CapsuleActive : " + preference.getCapsuleUuidActive());

            if (!preference.getLastCapsuleUuidActive().equals(preference.getCapsuleUuidActive())) {

                Log.d(TAG, "Capsule Progress : " + progressCapsule.getProgress());
                Log.d(TAG, "Capsule Completed : " + progressCapsule.getCompleted());
                Log.d(TAG, "Capsule Total slides : " + progressCapsule.getTotalSlides());
                Log.d(TAG, "Capsule View slides : " + progressCapsule.getViewSlides());

                if(progressCapsule.getCompleted() == 1) {
                    Log.d(TAG, "Capsule OLD returningAfterCompleted = " + progressCapsule.getReturningAfterCompleted());

                    int returningAfterCompleted = progressCapsule.getReturningAfterCompleted() + 1;

                    Log.d(TAG, "Capsule NEW returningAfterCompleted = " + returningAfterCompleted);
                    progressCapsule.setReturningAfterCompleted(returningAfterCompleted);
                }

                preference.setLastCapsuleUuidActive(capsule.getUuid());
                preference.save();

                Log.d(TAG, "Progress Capsule : setLastCapsuleActive : " + preference.getLastCapsuleUuidActive());
            }

            progressDao.update(progressCapsule);
        }
        try {
            JSONObject json = progressCapsule.toJson();
            json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_PROGRESS);

            sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
            syncDao.insert(sync);
        } catch (JSONException e) {

        }

        if(newRecord) {
            userLog = new UserLog();
            userLog.setUserUuid(preference.getUserUuid());
            userLog.setActivity(Constants.USER_LOG_ACTIVITY_START_CAPSULE);
            userLog.setCompanyUuid(topic.getCompanyUuid());
            userLog.setTopicUuid(topic.getUuid());
            userLog.setCapsuleUuid(capsule.getUuid());
            userLog.setAddedOn(dateOn);


            userLogDao.insert(userLog);
            try {
                JSONObject json = userLog.toJson();
                json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_USER_LOG);

                sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
                syncDao.insert(sync);
            } catch (JSONException e) {
            }
        }


        /*** FIN PROCESO CAPSULA ***/

        /*** INICIO USERLOG SLIDE ***/
        userLog = new UserLog();
        userLog.setUserUuid(preference.getUserUuid());
        userLog.setActivity(Constants.USER_LOG_ACTIVITY_VIEW_SLIDE);
        userLog.setCompanyUuid(topic.getCompanyUuid());
        userLog.setTopicUuid(topic.getUuid());
        userLog.setCapsuleUuid(capsule.getUuid());
        userLog.setSlideUuid(slide.getUuid());
        userLog.setAddedOn(dateOn);


        userLogDao.insert(userLog);
        try {
            JSONObject json = userLog.toJson();
            json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_USER_LOG);

            sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
            syncDao.insert(sync);
        } catch (JSONException e) {
        }

        /*** FIN ***/


        /*** PROGRESS SLIDE***/
        try {
            JSONObject json = progressSlide.toJson();
            json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_PROGRESS);

            sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
            syncDao.insert(sync);
        } catch (JSONException e) {
        }

        /** IS SLIDE = QUIZ **/
        if (isQuiz) {
            userLog = new UserLog();
            userLog.setUserUuid(preference.getUserUuid());
            userLog.setActivity(retakeQuiz ? Constants.USER_LOG_ACTIVITY_RETAKE_A_TEST : Constants.USER_LOG_ACTIVITY_TAKE_A_TEST);
            userLog.setCompanyUuid (topic.getCompanyUuid());
            userLog.setTopicUuid(slide.getTopicUuid());
            userLog.setCapsuleUuid(slide.getCapsuleUuid());
            userLog.setSlideUuid(slide.getUuid());
            userLog.setAddedOn(dateOn);

            userLogDao.insert(userLog);
            try {
                JSONObject json = userLog.toJson();
                json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_USER_LOG);

                sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
                syncDao.insert(sync);
            } catch (JSONException e) {
            }


            if(progressSlide.getCompleted() == 1) {
                userLog = new UserLog();
                userLog.setUserUuid(preference.getUserUuid());
                userLog.setActivity(Constants.USER_LOG_ACTIVITY_APPROVED_TEST);
                userLog.setCompanyUuid(topic.getCompanyUuid());
                userLog.setTopicUuid(slide.getTopicUuid());
                userLog.setCapsuleUuid(slide.getCapsuleUuid());
                userLog.setSlideUuid(slide.getUuid());
                userLog.setAddedOn(dateOn);

                userLogDao.insert(userLog);
                try {
                    JSONObject json = userLog.toJson();
                    json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_USER_LOG);

                    sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
                    syncDao.insert(sync);
                } catch (JSONException e) {
                }

            } else {
                if(progressSlide.getCompleted() == 1) {
                    userLog = new UserLog();
                    userLog.setUserUuid(preference.getUserUuid());
                    userLog.setActivity( Constants.USER_LOG_ACTIVITY_VIEW_SLIDE);
                    userLog.setCompanyUuid(topic.getCompanyUuid());
                    userLog.setTopicUuid(slide.getTopicUuid());
                    userLog.setCapsuleUuid(slide.getCapsuleUuid());
                    userLog.setSlideUuid(slide.getUuid());
                    userLog.setAddedOn(dateOn);

                    userLogDao.insert(userLog);
                    try {
                        JSONObject json = userLog.toJson();
                        json.put(Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME, Constants.SYNC_ADAPTER_DATA_TYPE_MICROLEARNING_USER_LOG);

                        sync = new Sync(Constants.SYNC_ADAPTER_TYPE_SYNC, json.toString());
                        syncDao.insert(sync);
                    } catch (JSONException e) {
                    }
                }
            }
        }

        requestExecuteSyncAdapter();
    }

    @Override
    public void launchVideoViewer(String videoAudioUrl)
    {

        Intent intent = new Intent(getApplicationContext(), VideoAudioActivity.class);
        intent.putExtra("videoAudioUrl",videoAudioUrl);
        intent.putExtra("deviceId", preference.getDeviceUuid());
        intent.putExtra("password", preference.getPassword());
        //startActivityForResult(intent, Constants.REQUEST_CODE_VIDEO);

        mLauncher.launch(intent);

    }

    @Override
    public void launchAudioViewer(String videoAudioUrl)
    {

        Intent intent = new Intent(getApplicationContext(), VideoAudioActivity.class);
        intent.putExtra("videoAudioUrl",videoAudioUrl);
        intent.putExtra("deviceId", preference.getDeviceUuid());
        intent.putExtra("password", preference.getPassword());
        //startActivityForResult(intent, Constants.REQUEST_CODE_AUDIO);


        mLauncher.launch(intent);
    }

    @Override
    public void launchTextViewer(String description)
    {
        Intent intent = new Intent(getApplicationContext(),TextActivity.class);
        intent.putExtra("description",description);

        //startActivityForResult(intent, Constants.REQUEST_CODE_TEXT);

        mLauncher.launch(intent);
    }


    @Override
    public void launchDocumentViewer(String file)
    {

        Intent intent = new Intent(getApplicationContext(),PdfActivity.class);
        intent.putExtra("documentUrl",file);
        intent.putExtra("deviceId", preference.getDeviceUuid());
        intent.putExtra("password", preference.getPassword());

        //startActivityForResult(intent, Constants.REQUEST_CODE_PDF);

        mLauncher.launch(intent);
    }

    @Override
    public void launchQuizViewer(String quizUuid)
    {

        ProgressDao progressDao = mAppDatabase.getProgressDao();
        Progress progress = progressDao.selectBySlideUuidAndUserUuid(preference.getSlideUuidActive(), preference.getUserUuid());

        boolean launch = false;
        if(progress != null && progress.getCompleted() == 0) {

            Calendar calendar = Calendar.getInstance();
            Date date = calendar.getTime();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.FORMAT_DATETIME_SERVICE);
            try {
                Long updateOn = simpleDateFormat.parse(progress.getUpdatedOn()).getTime();

                //30 minutes
                long mintime = 30 * 60 * 1000;
                if(date.getTime() - updateOn >  mintime ) {
                    launch = true;
                }

                launch = true;

            } catch(Exception e) {

            }


        } else {
            launch = true;
        }

        if(launch) {

            QuizDao quizDao = mAppDatabase.getQuizDao();
            Quiz quiz = quizDao.selectByUuid(quizUuid);

            TopicDao topicDao = mAppDatabase.getTopicDao();
            Topic topic = topicDao.selectByUuid(preference.getTopicUuidActive());

            CapsuleDao capsuleDao = mAppDatabase.getCapsuleDao();
            Capsule capsule = capsuleDao.selectByUuid(preference.getCapsuleUuidActive());

            SlideDao slideDao = mAppDatabase.getSlideDao();
            Slide slide = slideDao.selectByUuid(preference.getSlideUuidActive());

            QuestionDao questionDao = mAppDatabase.getQuestionDao();
            List<Question> questions = questionDao.selectAllByQuizUuid(quiz.getUuid());


            List<Answer> answers;
            AnswerDao answerDao = mAppDatabase.getAnswerDao();

            Intent intent = new Intent(getApplicationContext(), QuizActivity.class);
           // intent.putExtra("companyUuid", topic.getCompanyUuid());
           // intent.putExtra("topicUuid", topic.getUuid());
            //intent.putExtra("capsuleUuid", capsule.getUuid());
            //intent.putExtra("slideUuid", slide.getUuid());
            //intent.putExtra("userUuid", preference.getUserUuid());
            //intent.putExtra("quizUuid", quizUuid);


            intent.putExtra("quiz_uuid", quiz.getUuid());
            intent.putExtra("quiz_company_uuid", quiz.getCompanyUuid());
            intent.putExtra("quiz_name", quiz.getName());
            intent.putExtra("quiz_points", quiz.getPoints());
            intent.putExtra("quiz_max_time", quiz.getMaxTime());
            intent.putExtra("quiz_minimum_points_required", quiz.getMinimumPointsRequired());
            intent.putExtra("quiz_failed", quiz.getFailed());
            intent.putExtra("quiz_text", quiz.getText());

            intent.putExtra("questions", questions.size());
            int i = 1;
            int j = 1;
            for(Question question : questions) {
                intent.putExtra("question" + i + "_uuid", question.getUuid());
                intent.putExtra("question" + i + "_text", question.getText());
                intent.putExtra("question" + i + "_max_length", question.getMaxlength());
                intent.putExtra("question" + i + "_position", question.getPosition());
                intent.putExtra("question" + i + "_points", question.getPoints());
                intent.putExtra("question" + i + "_type", question.getType());

                answers = answerDao.selectAllByQuestionUuid(question.getUuid());
                intent.putExtra("question" + i + "_answers", answers.size());

                j = 1;
                for(Answer answer : answers) {
                    intent.putExtra("question" + i + "_answer_uuid" + j, answer.getUuid());
                    intent.putExtra("question" + i + "_answer_text" + j, answer.getText());
                    intent.putExtra("question" + i + "_answer_points" + j, answer.getPoints());
                    intent.putExtra("question" + i + "_answer_correct" + j, answer.getCorrect());
                    j++;
                }

                i++;
            }



            //startActivityForResult(intent, Constants.REQUEST_CODE_QUIZ);

            mLauncher.launch(intent);
        } else {
            showMessageSnackBar(getString(R.string.error_retry_quiz_min_time));
        }
    }


    @Override
    public Preference getPreference() {
        return preference;
    }

    @Override
    public void reloadNavHeader() {
        Log.d(TAG, "User Image = " + preference.getImage());
        navHeaderUserName.setText((preference.getFirstName() + " " + preference.getLastName()).trim());
        navHeaderUserEmail.setText(preference.getEmail());



        Log.d(TAG, preference.getImage());
        if(!TextUtils.isEmpty(preference.getImage())) {

            TimeZone timeZone = TimeZone.getTimeZone("UTC");
            Calendar calendar = Calendar.getInstance(timeZone);
            TimeZone tz = calendar.getTimeZone();
            int created =  (int) (calendar.getTimeInMillis() / 1000);

            Random random = new Random(created);
            int rand = 1000 + random.nextInt(8999);




            Log.d(TAG, "token = " + preference.getDeviceUuid());
            Log.d(TAG, "created = " + created);
            Log.d(TAG, "rand = " + rand);
            Log.d(TAG, "calc = " + preference.getPassword() + ':' +  created + ':' + rand);

            String secret = MD5.generar(preference.getPassword() + ':' +  created + ':' + rand);

            GlideUrl url = new GlideUrl(preference.getImage(), new LazyHeaders.Builder()
                    .addHeader(Constants.HTTP_HEADER_ACCEPT, Constants.HTTP_HEADER_ACCEPT_VALUE)
                    .addHeader(Constants.HTTP_HEADER_SECURITY_TOKEN, preference.getDeviceUuid())
                    .addHeader(Constants.HTTP_HEADER_SECURITY_SECRET, secret)
                    .addHeader(Constants.HTTP_HEADER_SECURITY_CREATED, String.valueOf(created))
                    .addHeader(Constants.HTTP_HEADER_SECURITY_RAND, String.valueOf(rand))
                    .build());

            RequestOptions options = new RequestOptions()
                    .diskCacheStrategy(DiskCacheStrategy.ALL);

            Glide.with(getApplicationContext()).load(url)
                    .thumbnail()
                    .apply(options)
                    .into(navHeaderUserImage);
        }
    }

    public void requestCheckChanges()
    {
        Log.d(TAG, "requestCheckChanges");
        try {

            CapsuleDao capsuleDao = mAppDatabase.getCapsuleDao();
            List<Capsule> capsules = capsuleDao.selectAll();

            if(capsules.size() > 0) {
                //ArrayList<String> ids = new ArrayList<>();

                TimeZone timeZone = TimeZone.getTimeZone("UTC");
                Calendar calendar = Calendar.getInstance(timeZone);
                TimeZone tz = calendar.getTimeZone();
                int created =  (int) (calendar.getTimeInMillis() / 1000);

                Random random = new Random(created);
                int rand = 1000 + random.nextInt(8999);


                //Log.d("requestCheckChanges", "token = " + preference.getDeviceUuid());
                //Log.d("requestCheckChanges", "created = " + created);
               // Log.d("requestCheckChanges", "rand = " + rand);
                //Log.d("requestCheckChanges", "calc = " + preference.password + ':' +  created + ':' + rand);

                String secret = MD5.generar(preference.getPassword() + ':' +  created + ':' + rand);

                //Log.d("requestCheckChanges", "secret = " + secret);


                FormBody.Builder formBodyCheckChangeBuilder = new FormBody.Builder();
                formBodyCheckChangeBuilder.add(Constants.POST_MICROLEARNING_CHECK_CHANGES_DEVICE_UUID, preference.getDeviceUuid());
                formBodyCheckChangeBuilder.add(Constants.POST_MICROLEARNING_CHECK_CHANGES_MAX_DATE_CHANGES, preference.getMaxDateChanges());
                formBodyCheckChangeBuilder.add(Constants.POST_MICROLEARNING_CHECK_CHANGES_IS_FOREGROUND, String.valueOf(isForeground ? 1 : 0));
                Http http = new Http(this.getCacheDir(), preference.getDeviceUuid(), secret, created, rand);
                OkHttpClient client = http.getHttpClient(false);



                formBodyCheckChangeBuilder.add(Constants.POST_MICROLEARNING_CHECK_CHANGES_MAX_IDS, String.valueOf(capsules.size()));
                //formBodyCheckChangeBuilder.add(Constants.POST_MICROLEARNING_CHECK_CHANGES_MAX_IDS, String.valueOf(0));

              int i = 1;
                for(Capsule capsule : capsules)
                {
                    Log.d("requestCheckChanges", "id" + i + " = " + capsule.getTopicUuid() + "|" + capsule.getUuid());


                    formBodyCheckChangeBuilder.add(Constants.POST_MICROLEARNING_CHECK_CHANGES_ID + i, capsule.getTopicUuid() + "|" + capsule.getUuid());
                    i++;
                }



                RequestBody formBody = formBodyCheckChangeBuilder.build();

                Log.d(TAG, "URL = " + Configuration.URL_CHECK_CHANGES);
                Request request = new Request.Builder()
                        .url(Configuration.URL_CHECK_CHANGES)
                        .post(formBody)
                        .build();

                Call call = client.newCall(request);
                call.enqueue(new okhttp3.Callback() {
                    public void onResponse(Call call, Response response)
                            throws IOException {



                        processResponseServerChanges(response.body().string());
                    }

                    public void onFailure(Call call, IOException e) {
                        Log.d(TAG, "Error :  " +  e.getMessage());
                    }
                });
            }



        } catch(Exception e) {

        }
    }


    public void syncFromServer(JSONObject data)
    {
        try {
            JSONObject objUser = data.getJSONObject("user");
            String userUuid = objUser.getString("uuid");


            AnswerDao answerDao = mAppDatabase.getAnswerDao();
            QuestionDao questionDao = mAppDatabase.getQuestionDao();
            QuizDao quizDao = mAppDatabase.getQuizDao();
            SlideDao slideDao = mAppDatabase.getSlideDao();
            CapsuleDao capsuleDao = mAppDatabase.getCapsuleDao();
            TopicDao topicDao = mAppDatabase.getTopicDao();
            CompanyDao companyDao = mAppDatabase.getCompanyDao();
            UserExtendedDao userExtendedDao = mAppDatabase.getUserExtendedDao();



            ProgressDao progressDao = mAppDatabase.getProgressDao();
            progressDao.removeAllUserUuidNotEqual(userUuid);


            UserLogDao userLogDao = mAppDatabase.getUserLogDao();
            userLogDao.removeAllUserUuidNotEqual(userUuid);

            JSONArray arrayCapsules;
            JSONArray arraySlides;
            JSONArray arrayAnswers;
            JSONArray arrayQuestions;
            JSONArray arrayProgress;
            JSONArray arrayQuizzes;
            JSONArray arrayUserLog;

            JSONObject objTopic;
            JSONObject objCapsule;
            JSONObject objSlide;
            JSONObject objAnswer;
            JSONObject objQuestion;
            JSONObject objQuiz;
            JSONObject objProgress;
            JSONObject objUserLog;
            int i,j,x;

            if(data.has("progress")) {

                arrayProgress = data.getJSONArray("progress");
                for (i = 0; i < arrayProgress.length(); i++) {
                    objProgress = arrayProgress.getJSONObject(i);


                    Progress progress = null;


                    userUuid = objProgress.getString("user_uuid");
                    String type = objProgress.getString("type");
                    String topicUuid = objProgress.getString("topic_uuid");
                    String capsuleUuid = objProgress.getString("capsule_uuid");
                    String slideUuid = objProgress.getString("slide_uuid");

                    if(type == Constants.PROGERSS_TYPE_SLIDE) {
                        progress = progressDao.selectBySlideUuidAndUserUuid(slideUuid, userUuid);
                    } else if(type == Constants.PROGERSS_TYPE_CAPSULE) {
                        progress = progressDao.selectByCapsuleUuidAndUserUuid(capsuleUuid, userUuid);
                    } else if(type == Constants.PROGERSS_TYPE_TOPIC) {
                        progress = progressDao.selectByTopicUuidAndUserUuid(topicUuid, userUuid);
                    }


                    if(progress == null) {
                        progress = new Progress();
                        progress.setUserUuid(userUuid);
                        progress.setCompanyUuid(objProgress.getString("company_uuid"));
                        progress.setTopicUuid(topicUuid);
                        progress.setCapsuleUuid(capsuleUuid);
                        progress.setSlideUuid(slideUuid);
                        progress.setProgress(objProgress.getDouble("progress"));
                        progress.setTotalSlides(objProgress.getInt("total_slides"));
                        progress.setViewSlides(objProgress.getInt("view_slides"));
                        progress.setType(type);
                        progress.setReturning(objProgress.getInt("returning"));
                        progress.setReturningAfterCompleted(objProgress.getInt("returning_after_completed"));
                        progress.setCompleted(objProgress.getInt("completed"));
                        progress.setAddedOn(objProgress.getString("added_on"));
                        progress.setUpdatedOn(objProgress.getString("updated_on"));

                        progressDao.insert(progress);
                    }


                }
            }

            if(data.has("userlog")) {
                arrayUserLog = data.getJSONArray("userlog");
                for (i = 0; i < arrayUserLog.length(); i++) {
                    objUserLog = arrayUserLog.getJSONObject(i);

                    userUuid = objUserLog.getString("user_uuid");
                    String activity = objUserLog.getString("activity");
                    String added_on = objUserLog.getString("added_on");

                    UserLog userLog = userLogDao.selectOneByUserUuidAndActivityAndAddedOn(userUuid, activity, added_on);
                    if(userLog == null) {
                        userLog = new UserLog();
                        userLog.setUserUuid(objUserLog.getString("user_uuid"));
                        userLog.setCompanyUuid(objUserLog.getString("company_uuid"));
                        userLog.setTopicUuid(objUserLog.getString("topic_uuid"));
                        userLog.setCapsuleUuid(objUserLog.getString("capsule_uuid"));
                        userLog.setSlideUuid(objUserLog.getString("slide_uuid"));
                        userLog.setActivity(objUserLog.getString("activity"));
                        userLog.setAddedOn(objUserLog.getString("added_on"));
                        userLogDao.insert(userLog);
                    }
                }
            }

            String uuid;
            Company company;
            if(data.has("quizzes")) {
                Quiz quiz;
                Question question;
                Answer answer;

                arrayQuizzes = data.getJSONArray("quizzes");
                for (i = 0; i < arrayQuizzes.length(); i++) {
                    objQuiz = arrayQuizzes.getJSONObject(i);


                    uuid = objQuiz.getString("company_uuid");
                    company = companyDao.selectByUuid(uuid);
                    if (company == null) {
                        company = new Company();
                        company.setUuid(objQuiz.getString("company_uuid"));
                        company.setName(objQuiz.getString("company_name"));
                        company.setImage(objQuiz.getString("company_image"));

                        companyDao.insert(company);
                    } else {
                        company.setName(objQuiz.getString("company_name"));
                        company.setImage(objQuiz.getString("company_image"));

                        companyDao.update(company);
                    }


                    uuid =  objQuiz.getString("uuid");
                    quiz = quizDao.selectByUuid(uuid);

                    if(quiz == null) {
                        quiz = new Quiz();
                        quiz.setUuid(  objQuiz.getString("uuid"));
                        quiz.setCompanyUuid(  company.getUuid() );
                        quiz.setFailed(  objQuiz.getString("failed"));
                        quiz.setName(  objQuiz.getString("name"));
                        quiz.setText(  objQuiz.getString("text"));
                        quiz.setPoints(  objQuiz.getInt("points"));
                        quiz.setMinimumPointsRequired(objQuiz.getInt("minimum_points_required"));
                        quiz.setMaxTime( objQuiz.getInt("max_time"));
                        quizDao.insert(quiz);

                    } else {
                        quiz.setCompanyUuid(  company.getUuid() );
                        quiz.setFailed(  objQuiz.getString("failed"));
                        quiz.setName(  objQuiz.getString("name"));
                        quiz.setText(  objQuiz.getString("text"));
                        quiz.setPoints(  objQuiz.getInt("points"));
                        quiz.setMinimumPointsRequired(objQuiz.getInt("minimum_points_required"));
                        quiz.setMaxTime( objQuiz.getInt("max_time"));
                        quizDao.update(quiz);
                    }

                    arrayQuestions = objQuiz.getJSONArray("questions");
                    for (j = 0; j < arrayQuestions.length(); j++) {
                        objQuestion = arrayQuestions.getJSONObject(j);

                        uuid = objQuestion.getString("uuid");
                        question = questionDao.selectByUuid(uuid);
                        if(question == null) {
                            question = new Question();
                            question.setQuizUuid( quiz.getUuid());
                            question.setUuid(uuid) ;
                            question.setText( objQuestion.getString("text"));
                            question.setType( objQuestion.getString("type"));
                            question.setPoints( objQuestion.getInt("points"));
                            question.setMaxlength( objQuestion.getInt("maxlength"));

                            questionDao.insert(question);
                        } else {
                            question.setQuizUuid( quiz.getUuid());
                            question.setText( objQuestion.getString("text"));
                            question.setType( objQuestion.getString("type"));
                            question.setPoints( objQuestion.getInt("points"));
                            question.setMaxlength( objQuestion.getInt("maxlength"));

                            questionDao.update(question);
                        }




                        arrayAnswers = objQuestion.getJSONArray("answers");
                        for (x = 0; x < arrayAnswers.length(); x++) {
                            objAnswer = arrayAnswers.getJSONObject(x);

                            uuid = objAnswer.getString("uuid");
                            answer = answerDao.selectByUuid(uuid);

                            if(answer == null) {

                                answer = new Answer();
                                answer.setQuestionUuid(question.getUuid());
                                answer.setUuid(uuid);
                                answer.setText(objAnswer.getString("text"));
                                answer.setPoints(objAnswer.getInt("points"));
                                answer.setCorrect(objAnswer.getString("correct"));

                                answerDao.insert(answer);
                            } else {
                                answer.setQuestionUuid(question.getUuid());
                                answer.setText(objAnswer.getString("text"));
                                answer.setPoints(objAnswer.getInt("points"));
                                answer.setCorrect(objAnswer.getString("correct"));
                                answerDao.update(answer);
                            }
                        }
                    }
                }
            }





            if(data.has("topics")) {
                Topic topic;
                Capsule capsule;
                Slide slide;

                JSONArray arrayTopics = data.getJSONArray("topics");
                for (i = 0; i < arrayTopics.length(); i++) {
                    objTopic = arrayTopics.getJSONObject(i);

                    uuid = objTopic.getString("company_uuid");
                    company = companyDao.selectByUuid(uuid);
                    if (company == null) {
                        company = new Company();
                        company.setUuid(objTopic.getString("company_uuid"));
                        company.setName(objTopic.getString("company_name"));
                        company.setImage(objTopic.getString("company_image"));

                        companyDao.insert(company);
                    } else {
                        company.setName(objTopic.getString("company_name"));
                        company.setImage(objTopic.getString("company_image"));

                        companyDao.update(company);
                    }

                    uuid = objTopic.getString("uuid");
                    topic = topicDao.selectByUuid(uuid);

                    if (topic == null) {
                        topic = new Topic();
                        topic.setUuid(uuid);
                        topic.setCompanyUuid(company.getUuid());
                        topic.setName(objTopic.getString("name"));
                        topic.setDescription(objTopic.getString("description"));
                        topic.setImage(objTopic.getString("image"));
                        topic.setPosition(objTopic.getInt("position"));
                        topicDao.insert(topic);
                    } else {
                        topic.setCompanyUuid(company.getUuid());
                        topic.setName(objTopic.getString("name"));
                        topic.setDescription(objTopic.getString("description"));
                        topic.setImage(objTopic.getString("image"));
                        topic.setPosition(objTopic.getInt("position"));
                        topicDao.update(topic);
                    }





                    arrayCapsules = objTopic.getJSONArray("capsules");
                    for (j = 0; j < arrayCapsules.length(); j++) {
                        objCapsule = arrayCapsules.getJSONObject(j);
                        uuid = objCapsule.getString("uuid");
                        capsule = capsuleDao.selectByUuid(uuid);
                        if(capsule == null) {
                            capsule = new Capsule();
                            capsule.setTopicUuid(topic.getUuid());
                            capsule.setUuid(uuid);
                            capsule.setName(objCapsule.getString("name"));
                            capsule.setDescription(objCapsule.getString("description"));
                            capsule.setImage(objCapsule.getString("image"));
                            capsule.setPosition(objCapsule.getInt("position"));
                            capsuleDao.insert(capsule);
                        } else {
                            capsule = new Capsule();
                            capsule.setTopicUuid(topic.getUuid());
                            capsule.setName(objCapsule.getString("name"));
                            capsule.setDescription(objCapsule.getString("description"));
                            capsule.setImage(objCapsule.getString("image"));
                            capsule.setPosition(objCapsule.getInt("position"));
                            capsuleDao.update(capsule);
                        }




                        arraySlides = objCapsule.getJSONArray("slides");
                        for (x = 0; x < arraySlides.length(); x++) {
                            objSlide = arraySlides.getJSONObject(x);

                            uuid = objSlide.getString("uuid");
                            slide = slideDao.selectByUuid(uuid);

                            if(slide == null) {

                                slide = new Slide();
                                slide.setUuid(uuid);
                                slide.setTopicUuid(capsule.getTopicUuid());
                                slide.setCapsuleUuid(capsule.getUuid());
                                slide.setQuizUuid(objSlide.getString("quiz_uuid"));
                                slide.setName(objSlide.getString("name"));
                                slide.setDescription(objSlide.getString("description"));
                                slide.setPosition(objSlide.getInt("position"));
                                slide.setType(objSlide.getString("type"));
                                slide.setFile(objSlide.getString("file"));
                                slide.setBackground(objSlide.getString("background"));

                                slideDao.insert(slide);
                            } else {
                                slide.setTopicUuid(capsule.getTopicUuid());
                                slide.setCapsuleUuid(capsule.getUuid());
                                slide.setQuizUuid(objSlide.getString("quiz_uuid"));
                                slide.setName(objSlide.getString("name"));
                                slide.setDescription(objSlide.getString("description"));
                                slide.setPosition(objSlide.getInt("position"));
                                slide.setType(objSlide.getString("type"));
                                slide.setFile(objSlide.getString("file"));
                                slide.setBackground(objSlide.getString("background"));

                                slideDao.update(slide);
                            }
                        }

                    }


                }
            }

            if(data.has( "extended")) {

                JSONObject objExtended;
                JSONObject objItem;
                JSONArray objItems;



                UserExtended userExtended;

                JSONArray extendedCompanies = data.getJSONArray("extended");
                for(i = 0 ; i < extendedCompanies.length(); i++)
                {
                    objExtended = extendedCompanies.getJSONObject(i);
                    if(objExtended.has("details")) {
                        uuid = objExtended.getString("company_uuid");


                        company = companyDao.selectByUuid(uuid);
                        if (company == null) {
                            company = new Company();
                            company.setUuid(objExtended.getString("company_uuid"));
                            company.setName(objExtended.getString("company_name"));
                            company.setImage(objExtended.getString("company_image"));

                            companyDao.insert(company);
                        } else {
                            company.setName(objExtended.getString("company_name"));
                            company.setImage(objExtended.getString("company_image"));

                            companyDao.update(company);
                        }

                        objItems = objExtended.getJSONArray("details");
                        for(j = 0 ; j < objItems.length(); j++) {
                            objItem = objItems.getJSONObject(j);

                            uuid =  objItem.getString("uuid");

                            userExtended = userExtendedDao.selectByUuid(uuid);
                            if(userExtended == null) {
                                userExtended = new UserExtended();
                                userExtended.setCompanyUuid(company.getUuid());
                                userExtended.setUuid(uuid);
                                userExtended.setLabel(objItem.getString("label"));
                                userExtended.setValue(objItem.getString("value"));
                                userExtendedDao.insert(userExtended);
                            } else {
                                userExtended.setCompanyUuid(company.getUuid());
                                userExtended.setLabel(objItem.getString("label"));
                                userExtended.setValue(objItem.getString("value"));
                                userExtendedDao.update(userExtended);
                            }




                        }
                    }
                }

            }


            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.FORMAT_DATETIME_SERVICE);
            if(data.has("max_date_changes")) {
                String max_date_changes = data.getString("max_date_changes");
                Log.d("syncFromServer", "max_date_changes : " + max_date_changes);

                if(!TextUtils.isEmpty(max_date_changes)) {
                    preference.setMaxDateChanges(max_date_changes);
                }
            } else {
                Log.d("syncFromServer", "No max_date_changes");
            }

            Calendar calendar = Calendar.getInstance();
            Date date = calendar.getTime();

            String  addedOn = simpleDateFormat.format(date);

            List<Company> companies = mAppDatabase.getCompanyDao().selectAll();
            int companySize = companies.size();

            if(companySize > 0) {

                if(TextUtils.isEmpty(preference.getCompanyUuidActive())) {

                    preference.setCompanyUuidActive(companies.get(0).getUuid());

                } else {

                    boolean companyExist = false;
                    for(i = 0; i < companies.size(); i++) {

                        if (companies.get(i).getUuid().equals(preference.getCompanyUuidActive())) {
                            companyExist = true;
                            break;
                        }
                    }

                    if(!companyExist && companies.size() > 0) {
                        preference.setCompanyUuidActive(companies.get(0).getUuid());
                    }
                }

            } else {
                preference.setCompanyUuidActive("");
            }



            preference.setLastDataRefresh(addedOn);
            preference.setCompanyCount(companySize);
            preference.save();

        } catch (JSONException e) {
            Log.d(TAG, e.getMessage());
        }
    }

    @Override
    public void requestExecuteSyncAdapter() {
            // Pass the settings flags by inserting them in a bundle
            Bundle settingsBundle = new Bundle();
            settingsBundle.putBoolean(
                    ContentResolver.SYNC_EXTRAS_MANUAL, true);
            settingsBundle.putBoolean(
                    ContentResolver.SYNC_EXTRAS_EXPEDITED, true);

            ContentResolver.requestSync(mAccount, Constants.AUTHORITY, settingsBundle);
    }


    private void processResponseServerChanges(String dataString)
    {

        Log.d(TAG, "processResponseServerChanges = " + dataString);

        try {
            JSONObject objJSON = new JSONObject(dataString);
            boolean success = objJSON.has("success") ? objJSON.getBoolean("success")  : false;


            if(success) {
                Calendar calendar = Calendar.getInstance();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.FORMAT_DATETIME_SERVICE);
                preference.setLastDataRefresh(simpleDateFormat.format(calendar.getTime()));
                preference.save();

                String max_date_changes = "";
                boolean processChanges = false;

                JSONObject data = objJSON.getJSONObject("data");
                if(data.has("max_date_changes") && data.has("new_capsules")) {
                    int new_capsules = data.getInt("new_capsules");
                    max_date_changes = data.getString("max_date_changes");




                    processChanges = new_capsules > 0 && !max_date_changes.equals(preference.getMaxDateChanges());
                } else {
                    processChanges = false;
                }

                if(processChanges && !max_date_changes.isEmpty()) {
                    int new_capsules = data.getInt("new_capsules");
                    String message = new_capsules == 1
                            ? "Hay 1 cápsula nueva disponible"
                            : "Hay " + new_capsules + " cápsulas disponible";


                    showMessageSnackBarWithClose(message);


                    preference.setMaxDateChanges(max_date_changes);

                    if(!isForeground) {
                        String body = new_capsules == 1
                                ? "Hay 1 cápsula nueva disponible"
                                : "Hay " + new_capsules + " cápsulas disponible";
                        showFcmNotification("Nuevo contenido", body, new_capsules);
                    }

                    /*
                    if(!isForeground) {
                        String body = new_capsules == 1
                                ? "Hay 1 cápsula nueva disponible"
                                : "Hay " + new_capsules + " cápsulas disponible";
                        showFcmNotification("Nuevo contenido", body, new_capsules);


                        AnswerDao answerDao = mAppDatabase.getAnswerDao();
                        answerDao.removeAll();

                        QuestionDao questionDao = mAppDatabase.getQuestionDao();
                        questionDao.removeAll();

                        QuizDao quizDao = mAppDatabase.getQuizDao();
                        quizDao.removeAll();

                        SlideDao slideDao = mAppDatabase.getSlideDao();
                        slideDao.removeAll();

                        CapsuleDao capsuleDao = mAppDatabase.getCapsuleDao();
                        capsuleDao.removeAll();

                        TopicDao topicDao = mAppDatabase.getTopicDao();
                        topicDao.removeAll();

                        CompanyDao companyDao = mAppDatabase.getCompanyDao();
                        companyDao.removeAll();

                        UserExtendedDao userExtendedDao = mAppDatabase.getUserExtendedDao();
                        userExtendedDao.removeAll();


                        this.syncFromServer(data);


                        if(!TextUtils.isEmpty(preference.getSlideUuidActive())) {

                            Slide slide = mAppDatabase.getSlideDao().selectByUuid(preference.getSlideUuidActive());
                            if(slide == null) {
                                preference.setFragmentIdxActive(Constants.IDX_FRAGMENT_TOPICS);
                                preference.save(this);
                            }

                        }
                    }*/
                }
            }
        } catch (JSONException e) {
            Log.d(TAG, e.getMessage());
        }
    }

    @Override
    public AppDatabase getDatabase() {
        return mAppDatabase;
    }

    @Override
    public void syncToServerOrCheckChanges()
    {
        if(TextUtils.isEmpty(preference.getDeviceUuid())) {
            return;
        }

        SyncDao syncDao = mAppDatabase.getSyncDao();
        List<Sync> records = syncDao.selectBatch();

        if(records.size() > 0) {
            syncToServer(records);
        } else {

                long timeLast = 0;
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.FORMAT_DATETIME_SERVICE);
                if (!TextUtils.isEmpty(preference.getLastDataRefresh())) {
                    try {
                        timeLast = simpleDateFormat.parse(preference.getLastDataRefresh()).getTime();
                    } catch (Exception e) {

                    }

                }


                Calendar calendar = Calendar.getInstance();
                long timeNow = calendar.getTime().getTime();
                 if (timeNow > (timeLast + Constants.CHECK_CHANGES_INTERVAL)) {
                    requestCheckChanges();
                }
        }
    }



    public void syncToServer(List<Sync> records)
    {



        int maxRecordsSyncBatch = 0;
        FormBody.Builder formBodyBatchBuilder = new FormBody.Builder();
        formBodyBatchBuilder.add(Constants.POST_SYNC_BATCH_FIELD_DEVICE_UUID, preference.getDeviceUuid());

        for(Sync record : records)
        {
            Log.d(TAG, "SyncRecord ID = " + record.getId() + " Data : "  + record.getData() + " Type= " + record.getType());

            if(record.getType() == Constants.SYNC_ADAPTER_TYPE_DEVICE && !isSyncDevice) {
                Log.d(TAG, "Device");
                isSyncDevice = true;

                try {
                    Http http = new Http(this.getCacheDir());
                    OkHttpClient client = http.getHttpClient(false);

                    RequestBody formBody = new FormBody.Builder()
                            .add(Constants.POST_DEVICE_FIELD_APPLICATION_ID,  String.valueOf(Configuration.APPLICATION_ID))
                            .add(Constants.POST_DEVICE_FIELD_DEVICE_UUID, preference.getDeviceUuid())
                            .add(Constants.POST_DEVICE_FIELD_MANUFACTURER, Build.MANUFACTURER)
                            .add(Constants.POST_DEVICE_FIELD_BRAND, Build.BRAND)
                            .add(Constants.POST_DEVICE_FIELD_VERSION, Build.VERSION.RELEASE  + " " + Build.VERSION_CODES.class.getFields()[android.os.Build.VERSION.SDK_INT].getName())
                            .add(Constants.POST_DEVICE_FIELD_MODEL, Build.MODEL)
                            .add(Constants.POST_DEVICE_FIELD_PLATFORM, "android")
                            .add(Constants.POST_DEVICE_FIELD_SYNC_ID, String.valueOf(record.getId()))
                            .build();

                    Log.d(TAG, "URL = " + Configuration.URL_DEVICE);
                    Request request = new Request.Builder()
                            .url(Configuration.URL_DEVICE)
                            .post(formBody)
                            .build();

                    Call call = client.newCall(request);
                    call.enqueue(new okhttp3.Callback() {
                        public void onResponse(Call call, Response response)
                                throws IOException {
                            isSyncDevice = false;
                            Log.d(TAG, "Response Device :  " +  response.body().toString());

                            processResponseSyncToServer(response.body().string());
                        }

                        public void onFailure(Call call, IOException e) {
                            isSyncDevice = false;
                            Log.d(TAG, "Error :  " +  e.getMessage());
                        }
                    });
                } catch (Exception e) {
                }
            }

            if(record.getType() == Constants.SYNC_ADAPTER_TYPE_FCM && !isSyncToken) {
                isSyncToken = true;
                Log.d(TAG, "FCM");

                try {
                    Http http = new Http(this.getCacheDir());
                    OkHttpClient client = http.getHttpClient(false);

                    RequestBody formBody = new FormBody.Builder()
                            .add(Constants.POST_FCM_FIELD_DEVICE_UUID,preference.getDeviceUuid())
                            .add(Constants.POST_FCM_FIELD_TOKEN, record.getData())
                            .add(Constants.POST_FCM_FIELD_SYNC_ID, String.valueOf(record.getId()))
                            .build();

                    Log.d(TAG, "URL = " + Configuration.URL_FCM);
                    Request request = new Request.Builder()
                            .url(Configuration.URL_FCM)
                            .post(formBody)
                            .build();

                    Call call = client.newCall(request);
                    call.enqueue(new okhttp3.Callback() {
                        public void onResponse(Call call, Response response)
                                throws IOException {
                            isSyncToken = false;
                            processResponseSyncToServer(response.body().string());
                        }

                        public void onFailure(Call call, IOException e) {
                            Log.d(TAG, "Error :  " +  e.getMessage());
                            isSyncToken = false;
                        }
                    });
                } catch (Exception e) {


                }
            }

            if(record.getType() == Constants.SYNC_ADAPTER_TYPE_SYNC ) {
                Log.d(TAG, "SYNC BATCH");
                maxRecordsSyncBatch++;
                formBodyBatchBuilder.add(Constants.POST_SYNC_BATCH_FIELD_RECORD_DATA + maxRecordsSyncBatch, record.getData());
                formBodyBatchBuilder.add(Constants.POST_SYNC_BATCH_FIELD_RECORD_SYNC_ID + maxRecordsSyncBatch, String.valueOf(record.getId()));
            }
        }


        if(maxRecordsSyncBatch > 0 && !isSyncBatch) {
            Log.d(TAG, "Sync Batch");
            isSyncBatch = true;

            try {
                Http http = new Http(this.getCacheDir());
                OkHttpClient client = http.getHttpClient(false);

                formBodyBatchBuilder.add(Constants.POST_SYNC_BATCH_FIELD_MAX_RECORDS, String.valueOf(maxRecordsSyncBatch));
                RequestBody formBody = formBodyBatchBuilder.build();

                Log.d(TAG, "URL = " + Configuration.URL_SYNC_BATCH);
                Request request = new Request.Builder()
                    .url(Configuration.URL_SYNC_BATCH)
                    .post(formBody)
                    .build();

                Call call = client.newCall(request);
                call.enqueue(new okhttp3.Callback() {
                    public void onResponse(Call call, Response response) throws IOException {
                        isSyncBatch = false;
                        processResponseServerBatch(response.body().string());
                    }

                    public void onFailure(Call call, IOException e) {
                        Log.d(TAG, "Error :  " +  e.getMessage());
                        isSyncBatch = false;
                    }
                });
            } catch (Exception e) {


            }
        }


    }

    private void processResponseServerBatch(String dataString)
    {
        boolean success = false;
        long sync_id = 0;

        Log.d(TAG, "processResponseServer = " + dataString);
        try {
            JSONObject objJSON = new JSONObject(dataString);
            success = objJSON.has("success") ? objJSON.getBoolean("success")  : false;
            if(success  && objJSON.has("data")) {
                JSONArray jsonArrayData = objJSON.getJSONArray("data");


                JSONObject jsonObjectData;
                int max = jsonArrayData.length();
                for(int i = 0; i < max; i++) {
                    jsonObjectData = jsonArrayData.getJSONObject(i);

                    if(jsonObjectData.has("success") && jsonObjectData.getBoolean("success")) {
                        sync_id = jsonObjectData.getLong("sync_id");

                        mAppDatabase.getSyncDao().remove(sync_id);

                    }


                }



                /*
                if(jsonObjectData.has("message")) {
                    message = jsonObjectData.getString("message");
                }

                if(jsonObjectData.has("aes")) {
                    preference.setAes(jsonObjectData.getString("aes"));
                    preference.save(this);
                }

                if(jsonObjectData.has("password")) {
                    preference.setPassword(jsonObjectData.getString("password"));
                    preference.save(this);
                }
                */
            }
            Log.d(TAG, "SyncID = " + sync_id);
            if(success && sync_id > 0) {
                Log.d(TAG, "DELETE SYNC RECORD : " + sync_id);
                mAppDatabase.getSyncDao().remove(sync_id);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void processResponseSyncToServer(String dataString)
    {
        boolean success = false;
        long sync_id = 0;

        Log.d(TAG, "processResponseServer = " + dataString);
        try {
            JSONObject objJSON = new JSONObject(dataString);
            success = objJSON.has("success") ? objJSON.getBoolean("success")  : false;
            if(success  && objJSON.has("data")) {
                JSONObject jsonObjectData = objJSON.getJSONObject("data");

                if(jsonObjectData.has("sync_id")) {
                    sync_id = jsonObjectData.getLong("sync_id");
                }

                /*
                if(jsonObjectData.has("message")) {
                    message = jsonObjectData.getString("message");
                }

                if(jsonObjectData.has("aes")) {
                    preference.setAes(jsonObjectData.getString("aes"));
                    preference.save(this);
                }

                if(jsonObjectData.has("password")) {
                    preference.setPassword(jsonObjectData.getString("password"));
                    preference.save(this);
                }
                */
            }
            Log.d(TAG, "SyncID = " + sync_id);
            if(success && sync_id > 0) {
                Log.d(TAG, "DELETE SYNC RECORD : " + sync_id);
                mAppDatabase.getSyncDao().remove(sync_id);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /*
    private void processResponseServerCheckChanges(String dataString) {

        Log.d(TAG, "processResponseServerCheckChanges = " + dataString);

        runOnUiThread(new Runnable() {

            @Override
            public void run() {

                try {
                    JSONObject objJSON = new JSONObject(dataString);
                    boolean success = objJSON.has("success") ? objJSON.getBoolean("success") : false;
                    String message = "";
                    if (objJSON.has("data")) {
                        Object item = objJSON.get("data");
                        if (item instanceof String) {
                            message = item.toString();
                        }
                    }

                    if (success) {
                        mAppDatabase.getAnswerDao().removeAll();
                        mAppDatabase.getQuestionDao().removeAll();
                        mAppDatabase.getQuizDao().removeAll();
                        mAppDatabase.getSlideDao().removeAll();
                        mAppDatabase.getCapsuleDao().removeAll();
                        mAppDatabase.getTopicDao().removeAll();


                        JSONObject data = objJSON.getJSONObject("data");
                        syncFromServer(data);


                    }


                } catch (JSONException e) {
                    Log.d(TAG, e.getMessage());
                }

                reloadNavHeader();


            }
        });
    }
     */



}