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

    if (fbAccessTokenTracker != null && fbAccessTokenTracker.isTracking()) {
      fbAccessTokenTracker.stopTracking();
    }

    if (fbProfileTracker != null && fbProfileTracker.isTracking()) {
      fbProfileTracker.stopTracking();
    }
  }
  @Override
  protected void onResume() {
    super.onResume();

    if (fbAccessTokenTracker != null && !fbAccessTokenTracker.isTracking()) {
      fbAccessTokenTracker.startTracking();
    }

    if (fbProfileTracker != null && !fbProfileTracker.isTracking()) {
      fbProfileTracker.startTracking();
    }
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    context = this;

    setContentView(R.layout.activity_register);

    activityLayout = findViewById(R.id.activity_register_layout);

    userNameInput = (EditText) findViewById(R.id.activity_register_input_username);
    fullNameInput = (EditText) findViewById(R.id.activity_register_input_fullname);
    emailInput = (EditText) findViewById(R.id.activity_register_input_email);
    passwordInput = (EditText) findViewById(R.id.activity_register_input_password);
    registerButton = (Button) findViewById(R.id.activity_register_action_register);
    existingUserButton = (Button) findViewById(R.id.activity_register_action_login);
    gPlusSignInButton = (Button) findViewById(R.id.activity_register_action_gpluslogin);
    facebookSignInButton = (Button) findViewById(R.id.activity_register_action_fblogin);

    usernameValidator = new UsernameValidator();
    emailValidator = new EmailValidator();
    passwordValidator = new PasswordValidator();

    final String passedEmail = getIntent().getStringExtra("emailAddress");
    if (passedEmail != null) {
      emailInput.setText(passedEmail);
    }

    requestQueue = VolleyRequestQueueSingleton.getInstance(this).getRequestQueue();

    existingUserButton.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            startActivity(new Intent(context, LoginActivity.class));
            finish();
          }
        });

    registerButton.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            userName = userNameInput.getText().toString();
            fullName = fullNameInput.getText().toString();
            emailAddress = emailInput.getText().toString();
            password = passwordInput.getText().toString();

            boolean isUserNameValid, isEmailValid, isPasswordValid;

            isUserNameValid = usernameValidator.validate(userName);
            isEmailValid = emailValidator.validate(emailAddress);
            isPasswordValid = passwordValidator.validate(password);

            if (isUserNameValid && isEmailValid && isPasswordValid) {
              progressDialog = ProgressDialog.show(context, null, "Please wait", true);
              APIRequests.registerDirectUser(
                  context,
                  userName,
                  fullName,
                  emailAddress,
                  password,
                  new APIResponseCallback() {
                    @Override
                    public void success(String apiResponse) {
                      try {
                        JSONObject apiResponseJSON = new JSONObject(apiResponse);
                        String accessToken = apiResponseJSON.optString("token");
                        UserHelper.saveAccessToken(context, accessToken);
                        proceedSuccessfulSignUp();
                      } catch (JSONException e) {
                        e.printStackTrace();
                        if (progressDialog != null) {
                          progressDialog.dismiss();
                          Snackbar.make(
                                  activityLayout, "Error parsing response.", Snackbar.LENGTH_LONG)
                              .show();
                        }
                      }
                    }

                    @Override
                    public void error(VolleyError error) {
                      if (progressDialog != null) {
                        progressDialog.dismiss();
                        Snackbar.make(
                                activityLayout,
                                ResponseHelper.getMessageFromApiErrorResponse(error),
                                Snackbar.LENGTH_LONG)
                            .show();
                      }
                    }
                  });
            } else {
              if (!isUserNameValid) {
                userNameInput.setError(
                    "Please use only letters, numbers, underscores and hyphens.");
              }
              if (!isEmailValid) {
                emailInput.setError("Please enter a valid email address");
              }
              if (!isPasswordValid) {
                passwordInput.setError(
                    "Please use only letters, numbers, underscores and hyphens.");
              }
            }
          }
        });

    facebookSignInButton.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            List<String> permissionNeeds = Arrays.asList("public_profile", "email", "user_friends");
            LoginManager.getInstance()
                .logInWithReadPermissions((Activity) context, permissionNeeds);
            LoginManager.getInstance()
                .registerCallback(
                    fbCallbackManager,
                    new FacebookCallback<LoginResult>() {
                      @Override
                      public void onSuccess(LoginResult loginResult) {
                        progressDialog = ProgressDialog.show(context, null, "Please wait", true);
                        AccessToken accessToken = loginResult.getAccessToken();
                        GraphRequest graphRequest =
                            GraphRequest.newMeRequest(
                                accessToken,
                                new GraphRequest.GraphJSONObjectCallback() {
                                  @Override
                                  public void onCompleted(
                                      JSONObject userJSON, GraphResponse graphResponse) {
                                    fbEmail = userJSON.optString("email");
                                    fbFullName =
                                        userJSON.optString("first_name")
                                            + " "
                                            + userJSON.optString("last_name");
                                    fbId = userJSON.optString("id");
                                  }
                                });
                        Bundle parameters = new Bundle();
                        parameters.putString("fields", "id, first_name, last_name, email");
                        graphRequest.setParameters(parameters);

                        graphRequest.executeAsync();

                        if (accessToken != null) {
                          Log.d("LOGIN", "AccessToken: " + accessToken.getToken());
                        }
                      }

                      @Override
                      public void onCancel() {
                        Log.d("LOGIN", "Cancelled");
                      }

                      @Override
                      public void onError(FacebookException e) {
                        Log.d("LOGIN", "Error");
                      }
                    });
          }
        });

    fbCallbackManager = CallbackManager.Factory.create();

    // Start tracking the changes in fb access token
    fbAccessTokenTracker =
        new AccessTokenTracker() {
          @Override
          protected void onCurrentAccessTokenChanged(
              AccessToken accessToken, AccessToken accessToken1) {
            if (accessToken != null) {
              Log.d("LOGIN", "Old access token " + accessToken.getToken());
            }
            if (accessToken1 != null) {
              Log.d("LOGIN", "New access token " + accessToken1.getToken());
            }
          }
        };
    fbAccessTokenTracker.startTracking();

    // Start tracking changes in fb profile
    fbProfileTracker =
        new ProfileTracker() {
          @Override
          protected void onCurrentProfileChanged(Profile profile, Profile profile1) {
            if (profile != null) {
              Log.d("LOGIN", "Old profile id " + profile.getId());
            }
            if (profile1 != null) {
              Log.d("LOGIN", "New profile id " + profile1.getId());
            }
          }
        };
    fbProfileTracker.startTracking();

    statusesToHandle = new ArrayList<>();
    statusesToHandle.add(1);
    statusesToHandle.add(2);
    statusesToHandle.add(3);
    statusesToHandle.add(5);
    statusesToHandle.add(7);
    statusesToHandle.add(8);
    statusesToHandle.add(9);
    statusesToHandle.add(11);
    statusesToHandle.add(17);
    statusesToHandle.add(18);

    googleApiClient =
        new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API)
            .addScope(Plus.SCOPE_PLUS_LOGIN)
            .build();

    gPlusSignInButton.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            progressDialog = ProgressDialog.show(context, null, "Please wait", true);
            if (!googleApiClient.isConnecting()) {
              gPlusSignInClicked = true;
              googleApiClient.connect();
            }
          }
        });
  }