package edu.gatech.oad.rocket.findmythings;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import edu.gatech.oad.rocket.findmythings.model.MessageBean;
import edu.gatech.oad.rocket.findmythings.service.EndpointUtils;
import edu.gatech.oad.rocket.findmythings.service.Fmthings;
import edu.gatech.oad.rocket.findmythings.util.*;
import edu.gatech.oad.rocket.findmythings.util.validation.EmailValidator;
import java.io.IOException;
/**
* CS 2340 - FindMyStuff Android App
* Activity that takes care of registration of a new member
*
* @author TeamRocket
* */
public class RegisterActivity extends Activity {
/**
* Form values.
*/
private String mEmail, mPassword, mCon, mPhone, mName, mAddress;
/**
* Copied email address from the login window.
*/
public static String rEmail = "";
/**
* UI references.
*/
private EditText mEmailView;
private EditText mPasswordView;
private EditText mPhoneView;
private EditText mAddressView;
private EditText mNameView;
private EditText mConfirmView;
private View focusView;
private View mStatusForm;
private View mStatusView;
private TextView mStatusMessageView;
/**
* Keep track of the task to ensure we can cancel it if requested.
*/
private RegisterUserTask mSubmitTask = null;
/**
* creates new window with correct layout
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
// Hide the Up button in the action bar.
setupActionBar();
// Gets mEmail from LoginActivity
Intent i = getIntent();
String s = i.getExtras().getString("email");
if (s == null) s = "";
mEmailView = (EditText) findViewById(R.id.email);
mEmailView.setText(s);
rEmail = s;
mPasswordView = (EditText) findViewById(R.id.pass);
mAddressView = (EditText) findViewById(R.id.address);
mNameView = (EditText) findViewById(R.id.lookingfor);
mConfirmView = (EditText) findViewById(R.id.confirmpass);
mPhoneView = (EditText) findViewById(R.id.phone);
mPhoneView.addTextChangedListener(new PhoneNumberTextWatcher());
mPhoneView.setFilters(new InputFilter[] { new PhoneNumberFilter(), new InputFilter.LengthFilter(14) });
mStatusForm = findViewById(R.id.register_form);
mStatusView = findViewById(R.id.register_status);
mStatusMessageView = (TextView) findViewById(R.id.register_status_message);
}
/**
* deals with action to do once a key is pressed down
* @param keyCode - key pressed
* @param event - event to do in case of pressed
* @return true when done
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//Tells Activity what to do when back key is pressed
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
super.onBackPressed();
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Set up the {@link android.app.ActionBar}.
*/
private void setupActionBar() {
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setDisplayShowHomeEnabled(true);
}
private boolean containsNoErrors() {
if (TextUtils.isEmpty(mPassword)) {
mPasswordView.setError(getString(R.string.error_field_required));
focusView = mPasswordView;
return false;
} else if (TextUtils.isEmpty(mEmail)) {
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
return false;
} else if (!EmailValidator.getInstance().isValid(mEmail)) {
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
return false;
} else if (!mPassword.equals(mCon)) {
mPasswordView.setError(getString(R.string.error_passwords_match));
focusView = mPasswordView;
return false;
}
return true;
}
/**
* RegisterActivity new user and return to login screen
* or just move on to the main screen with the newly created user
* already logged in.
*/
private boolean attemptToRegister() {
mEmail = mEmailView.getText().toString();
mPassword = mPasswordView.getText().toString();
mPhone = mPhoneView.getText().toString();
mCon = mConfirmView.getText().toString();
mName = mNameView.getText().toString();
mAddress = mAddressView.getText().toString();
if (mSubmitTask != null) {
return false;
}
if (containsNoErrors()) {
mStatusMessageView.setText(R.string.submit_progress_message);
showProgress(true);
mSubmitTask = new RegisterUserTask();
mSubmitTask.execute();
return true;
} else {
focusView.requestFocus();
return false;
}
}
/**
* creates the options menu
* @param menu
* @return true when done
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.register, menu);
return true;
}
/**
* deals with action when an options button is selected
* @param item
* @return boolean
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.register_ok:
return attemptToRegister();
case R.id.register_cancel:
case android.R.id.home:
return toLogin(false);
}
return super.onOptionsItemSelected(item);
}
/**
* Shows the progress UI and hides the form.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(
android.R.integer.config_shortAnimTime);
mStatusView.setVisibility(View.VISIBLE);
mStatusView.animate().setDuration(shortAnimTime)
.alpha(show ? 1 : 0)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
mStatusForm.setVisibility(View.VISIBLE);
mStatusForm.animate().setDuration(shortAnimTime)
.alpha(show ? 0 : 1)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mStatusForm.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
} else {
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
mStatusForm.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
/**
* Represents an asynchronous submission task used to upload an item.
*/
public class RegisterUserTask extends AsyncTask<Void, Void, MessageBean> {
@Override
protected MessageBean doInBackground(Void... param) {
try {
Fmthings.Account.Register op = EndpointUtils.getEndpoint().account().register(mEmail, mPassword, mCon);
if (mPhone != null) op.setPhone(mPhone);
if (mName != null) op.setName(mName);
if (mAddress != null) op.setAddress(mAddress);
return op.execute();
} catch (IOException e) {
return null;
}
}
/**
* deals with action when registered either successfully or not
* @param output - response from the API method
*/
@Override
protected void onPostExecute(final MessageBean output) {
mSubmitTask = null;
String status = null, failureMessage = null;
if (output != null) {
status = output.getMessage();
failureMessage = output.getFailureReason();
}
Messages.Register failureType = EnumHelper.forTextString(Messages.Register.class, failureMessage);
if (status != null && status.equals(Messages.Status.OK.getText())) {
toLogin(true);
} else if (failureType != null){
switch (failureType) {
case ALREADY_USER:
mEmailView.setError(getString(R.string.error_already_user));
mEmailView.requestFocus();
break;
case BAD_EMAIL_ADDRESS:
mEmailView.setError(getString(R.string.error_invalid_email));
mEmailView.requestFocus();
break;
case BAD_PASSWORD:
mPasswordView.setError(getString(R.string.error_short_password));
mPasswordView.requestFocus();
break;
case PASSWORDS_MATCH:
mPasswordView.setError(getString(R.string.error_passwords_match));
mPasswordView.requestFocus();
break;
case INVALID_PHONE:
mPhoneView.setError(getString(R.string.error_invalid_phone));
mPhoneView.requestFocus();
break;
default:
ToastHelper.showError(RegisterActivity.this, getString(R.string.error_invalid_data));
break;
}
} else {
ToastHelper.showError(RegisterActivity.this, getString(R.string.error_no_response));
}
showProgress(false);
}
/**
* deals with action when task cancelled
*/
@Override
protected void onCancelled() {
mSubmitTask = null;
showProgress(false);
}
}
/**
* Called to pop the login window from the navigation stack
*/
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_right);
}
/**
* Returns to the login window either as a result of registering or hitting back
* @param registered true to push log in, false to pop
* @return true, always true. Why? Because.
*/
private boolean toLogin(boolean registered) {
finish();
if (registered) overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_left);
return true;
}
}