package com.nbs.client.assassins.views;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Parcelable;
import android.support.v4.app.DialogFragment;
import android.text.format.Time;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragment;
import com.google.android.gms.maps.model.LatLng;
import com.googlecode.androidannotations.annotations.AfterInject;
import com.googlecode.androidannotations.annotations.Background;
import com.googlecode.androidannotations.annotations.Click;
import com.googlecode.androidannotations.annotations.EFragment;
import com.googlecode.androidannotations.annotations.TextChange;
import com.googlecode.androidannotations.annotations.UiThread;
import com.googlecode.androidannotations.annotations.ViewById;
import com.googlecode.androidannotations.annotations.rest.RestService;
import com.nbs.client.assassins.R;
import com.nbs.client.assassins.controllers.CustomizeMatchActivity;
import com.nbs.client.assassins.controllers.MatchBoundsActivity;
import com.nbs.client.assassins.models.App;
import com.nbs.client.assassins.models.Match;
import com.nbs.client.assassins.models.Repository;
import com.nbs.client.assassins.models.User;
import com.nbs.client.assassins.network.CreateMatchRequest;
import com.nbs.client.assassins.network.HuntedRestClient;
import com.nbs.client.assassins.network.MatchResponse;
import com.nbs.client.assassins.utils.LocationUtils;
import com.nbs.client.assassins.views.DatePickerDialogFragment.OnDatePickedListener;
import com.nbs.client.assassins.views.TimePickerDialogFragment.OnTimePickedListener;
@EFragment(R.layout.create_match_fragment)
public class CreateMatchFragment extends SherlockFragment
implements OnDatePickedListener, OnTimePickedListener {
private static final String TAG = "CreateMatchFragment";
// Container Activity must implement this interface
public interface OnMatchCreatedListener {
public void onMatchCreated(boolean wasCreated);
}
private static final int MIN_PASSWORD_LEN = 6;
private static final int MIN_MATCH_NAME_LEN = 6;
private static final int GAMEPLAY_ACTIVITY_REQUEST = 0;
private static final int BOUNDS_ACTIVITY_REQUEST = 1;
public OnMatchCreatedListener mListener;
@ViewById(R.id.create_match)
public Button btnCreate;
@ViewById(R.id.edit_match_name)
public EditText matchName;
@ViewById(R.id.manual_start)
public CheckBox manualStart;
@ViewById(R.id.join_on_create)
public CheckBox joinOnCreate;
@ViewById(R.id.edit_match_password)
public EditText password;
@ViewById(R.id.boundaries)
public Button selectBoundaries;
@ViewById(R.id.gameplay)
public Button gameplaySettings;
@ViewById(R.id.start_date)
public Button startDate;
@ViewById(R.id.start_time)
public Button startTime;
@RestService
public HuntedRestClient restClient;
public Integer minute;
public Integer hourOfDay;
public Integer monthDay;
public Integer month;
public Integer year;
public LatLng nwCorner;
public LatLng seCorner;
public Double aRange;
public Double hRange;
public Integer tEscape;
//@ViewById(R.id.join_when_create_match)
//Switch join;
//match parameters
public CreateMatchFragment() {}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnMatchCreatedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnMatchCreatedListener");
}
}
@TextChange({R.id.edit_match_name, R.id.edit_match_password})
void onTextChangesOnSomeTextViews(TextView tv, CharSequence text) {
}
@Click(R.id.manual_start)
void onManualStartChanged() {
boolean isManualStart = manualStart.isChecked();
int textColor = isManualStart ? R.color.gray : R.color.black;
startTime.setEnabled(!isManualStart); startTime.setTextColor(textColor);
startDate.setEnabled(!isManualStart); startDate.setTextColor(textColor);
}
@Click(R.id.boundaries)
void onSelectBoundariesClicked() {
Log.i(TAG, "onSelectBoundariesClicked()");
hideKeyboard();
Intent boundariesIntent = new Intent(getSherlockActivity(), MatchBoundsActivity.class);
startActivityForResult(boundariesIntent, BOUNDS_ACTIVITY_REQUEST);
}
@Click(R.id.gameplay)
void onGameplaySettingsClicked() {
Log.i(TAG, "onGameplaySettingsClicked()");
hideKeyboard();
Intent intent = new Intent(getSherlockActivity(), CustomizeMatchActivity.class);
startActivityForResult(intent, GAMEPLAY_ACTIVITY_REQUEST);
}
@Click(R.id.start_date)
void onStartDateClicked() {
Log.i(TAG, "onStartDateClicked()");
hideKeyboard();
DialogFragment newFragment =
DatePickerDialogFragment.newInstance("Start Date");
((DatePickerDialogFragment)newFragment).setOnDatePickedListener(this);
newFragment.show(getFragmentManager(), "start date dialog");
}
@Click(R.id.start_time)
void onStartTimeClicked() {
Log.i(TAG, "onStartTimeClicked()");
hideKeyboard();
DialogFragment newFragment =
TimePickerDialogFragment.newInstance("Start Time");
((TimePickerDialogFragment)newFragment).setOnTimePickedListener(this);
newFragment.show(getFragmentManager(), "start time dialog");
}
@Click(R.id.create_match)
void onCreateMatchClicked() {
//TODO: validate name and password before allowing button to be enabled
//TODO: show visual indication if there are validation issues
Log.i(TAG, password.getText().toString());
if(hasValidSettings()) {
InputMethodManager imm = (InputMethodManager)getSherlockActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
btnCreate.setEnabled(false);
//startTime remains null if manualStart is checked
Time startTime = null;
if(!manualStart.isChecked()) {
startTime = new Time();
startTime.set(0, minute, hourOfDay, monthDay, month, year);
}
String passwordStr = password.getText().toString();
Repository model = App.getRepo();
User user = model.getUser();
CreateMatchRequest request =
new CreateMatchRequest(user.getToken(),
new Match(matchName.getText().toString(),
passwordStr.length() >= MIN_PASSWORD_LEN ? passwordStr : null,
user.getUsername(),
((startTime != null) ? startTime.toMillis(false) : null),
nwCorner, seCorner,
aRange, hRange, tEscape));
request.joinOnCreate = joinOnCreate.isChecked();
Log.i(TAG, "Creating Match " + request.toString());
createMatchInBackground(request,
ProgressDialog.show(getActivity(), "Please Wait", "Creating match...", true, false));
}
}
private boolean hasValidSettings() {
String passwordStr = password.getText().toString();
String validationMsg = "";
if(passwordStr.length() < MIN_PASSWORD_LEN && passwordStr.length() != 0) {
validationMsg += "Password at least " + MIN_PASSWORD_LEN + " chars ";
}
if(matchName.getText().toString().length() < MIN_MATCH_NAME_LEN) {
validationMsg += "Match name at least " + MIN_MATCH_NAME_LEN +" chars ";
}
if((minute == null || month == null) && !manualStart.isChecked()) {
validationMsg += "Choose a start time or select manual start ";
}
if(nwCorner == null) {
validationMsg += "Choose boundaries ";
}
if(aRange == null) {
validationMsg += "Set Gameplay settings";
}
boolean isValid = (validationMsg == "");
if(!isValid) {
Toast.makeText(getActivity(), validationMsg, Toast.LENGTH_LONG).show();
}
return isValid;
}
@Background
void createMatchInBackground(CreateMatchRequest msg, ProgressDialog progress) {
MatchResponse response = null;
try {
response = restClient.createMatch(msg);
}
catch(Exception e) {
Log.i(TAG, "EXCEPTION: " + e.toString());
}
matchCreatedResult(response, progress);
}
@UiThread
void matchCreatedResult(MatchResponse response, ProgressDialog progress) {
progress.dismiss();
if(response != null) {
Toast.makeText(getActivity(), response.message, Toast.LENGTH_SHORT).show();
Log.d(TAG, response.toString());
if(response.ok() && joinOnCreate.isChecked()) {
Repository model = App.getRepo();
model.createOrUpdateMatch(response.match);
Log.d(TAG, "player from match: " + model.getMyPlayer(response.match.id));
}
mListener.onMatchCreated(response.ok());
btnCreate.setEnabled(!response.ok());
} else {
btnCreate.setEnabled(true);
Toast.makeText(getActivity(), "Network error.", Toast.LENGTH_LONG).show();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult(result:"+resultCode+")");
if(resultCode == Activity.RESULT_OK) {
if(requestCode == BOUNDS_ACTIVITY_REQUEST) {
String description = data.getStringExtra("description");
Parcelable[] points = data.getParcelableArrayExtra("points");
LatLng[] latLngPoints = new LatLng[points.length];
for(int i = 0; i < points.length; i++) {
latLngPoints[i] = ((LatLng)points[i]);
}
nwCorner = latLngPoints[0];
seCorner = latLngPoints[1];
Log.d(TAG, "Bounds [nw:" + nwCorner + "] [se:" + seCorner + "]");
String text = LocationUtils.getMilesAreaString(latLngPoints[0], latLngPoints[1]) +
((description != null) ? " (" + description + ")" : "");
selectBoundaries.setText(text);
selectBoundaries.setTextColor(getResources().getColor(R.color.abs__bright_foreground_holo_light));
} else if (requestCode == GAMEPLAY_ACTIVITY_REQUEST) {
tEscape = data.getIntExtra("wait", -1);
aRange = data.getDoubleExtra("aRange",-1.0d);
hRange = data.getDoubleExtra("hRange",-1.0d);
gameplaySettings.setText("hunt: " + hRange + "mi, " +
"attack: " + aRange + "mi, " +
tEscape + "s" );
gameplaySettings.setTextColor(getResources()
.getColor(R.color.abs__bright_foreground_holo_light));
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void hideKeyboard() {
InputMethodManager inputManager = (InputMethodManager)
getSherlockActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getSherlockActivity().getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
@Override
public void onDatePicked(int year, int monthOfYear, int dayOfMonth) {
startDate.setText(TimeUtils.formatDate(year, monthOfYear, dayOfMonth));
startDate.setTextColor(getResources()
.getColor(R.color.abs__bright_foreground_holo_light));
this.year = year;
this.monthDay = dayOfMonth;
this.month = monthOfYear;
}
@Override
public void onTimePicked(int hourOfDay, int minute) {
startTime.setText(TimeUtils.formatTime(hourOfDay, minute));
startTime.setTextColor(getResources()
.getColor(R.color.abs__bright_foreground_holo_light));
this.hourOfDay = hourOfDay;
this.minute = minute;
}
@AfterInject
public void afterInjection() {
//subvert a bug in HttpUrlConnection
//see: http://www.sapandiwakar.in/technical/eofexception-with-spring-rest-template-android/
restClient.getRestTemplate().setRequestFactory(
new HttpComponentsClientHttpRequestFactory());
}
}