package org.azavea.otm.ui;
import java.io.UnsupportedEncodingException;
import java.util.Vector;
import org.azavea.otm.App;
import org.azavea.otm.R;
import org.azavea.otm.data.PendingEditDescription;
import org.azavea.otm.data.Plot;
import org.azavea.otm.rest.RequestGenerator;
import org.azavea.otm.rest.handlers.LoggingJsonHttpResponseHandler;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import com.loopj.android.http.JsonHttpResponseHandler;
import cz.msebera.android.httpclient.Header;
public class PendingItemDisplay extends Activity {
// We will need the key IE "tree.dbh" so that we can find the pending
// edits in the plot
String key;
// We are going to manage the current and pending values
// through the CheckBox objects that we instantiate for them.
CheckBox selectedValue;
CheckBox currentValue;
Vector<CheckBox> allPending = new Vector<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pending_item);
/*Render
+ label (IE "Diameter a Breast Height (in)")
+ current value (the value in the db that has been prev approved)
+ pending values
+ next/cancel buttons
*/
String label = getIntent().getStringExtra("label");
if (label != null && !label.equals("")) {
renderTitle(label);
}
String current = getIntent().getStringExtra("current");
renderCurrentValue(current);
String pending = getIntent().getStringExtra("pending");
if (pending != null && !pending.equals("")) {
try {
renderPendingValues(new JSONArray(getIntent().getStringExtra("pending")));
} catch (JSONException e) {
Toast.makeText(PendingItemDisplay.this, "Error rendering pending edits", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
renderApprovalButtons();
}
public boolean canApprovePendingEdits() {
if (App.getLoginManager().isLoggedIn()) {
return App.getLoginManager().loggedInUser.isAdmin();
} else {
return false;
}
}
private void renderCurrentValue(String value) {
View row = getLayoutInflater().inflate(R.layout.pending_edit_row, null);
ViewGroup container = (ViewGroup) findViewById(R.id.currentValue);
currentValue = (CheckBox) row.findViewById(R.id.checkBox);
((TextView) row.findViewById(R.id.user_name)).setText("");
((TextView) row.findViewById(R.id.date)).setText("");
if (value == null || value.equals("")) { // no current value.
((TextView) row.findViewById(R.id.value)).setText("No current value");
} else {
((TextView) row.findViewById(R.id.value)).setText(value);
if (canApprovePendingEdits()) {
currentValue.setOnClickListener(checkBoxClickListener);
currentValue.setVisibility(View.VISIBLE);
}
}
container.addView(row);
}
private void renderPendingValues(JSONArray pendingEdits) {
ViewGroup container = (ViewGroup) findViewById(R.id.pendingEdits);
for (int i = 0; i < pendingEdits.length(); i++) {
JSONObject pendingEdit;
try {
pendingEdit = pendingEdits.getJSONObject(i);
String value = pendingEdit.getString("value");
String username = pendingEdit.getString("username");
String date = pendingEdit.getString("date");
int id = pendingEdit.getInt("id");
View pendingRow = getLayoutInflater().inflate(R.layout.pending_edit_row, null);
((TextView) pendingRow.findViewById(R.id.value)).setText(value);
((TextView) pendingRow.findViewById(R.id.date)).setText(date);
((TextView) pendingRow.findViewById(R.id.user_name)).setText(username);
if (canApprovePendingEdits()) {
CheckBox cb = (CheckBox) pendingRow.findViewById(R.id.checkBox);
allPending.add(cb);
cb.setOnClickListener(checkBoxClickListener);
cb.setTag(id);
cb.setVisibility(View.VISIBLE);
}
container.addView(pendingRow);
} catch (JSONException e) {
Toast.makeText(PendingItemDisplay.this, "Error rendering pending edits", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}
private void renderTitle(String label) {
((TextView) findViewById(R.id.pending_edit_label)).setText(label);
}
private void renderApprovalButtons() {
if (canApprovePendingEdits()) {
findViewById(R.id.nav).setVisibility(View.VISIBLE);
}
}
public OnClickListener checkBoxClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
selectedValue = (CheckBox) v;
currentValue.setChecked(currentValue == v);
for (CheckBox cc : allPending) {
cc.setChecked(v == cc);
}
}
};
public void handleSaveClick(View view) {
if (selectedValue == null) {
Toast.makeText(PendingItemDisplay.this, "Please select an item.", Toast.LENGTH_SHORT).show();
} else if (selectedValue == currentValue) {
try {
rejectAll();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(this, "There was a problem saving the pending edits", Toast.LENGTH_LONG).show();
}
} else {
approve(selectedValue);
}
}
private void approve(CheckBox c) {
RequestGenerator rc = new RequestGenerator();
Object tag = c.getTag();
if (tag != null) {
Integer idToApprove = null;
try {
idToApprove = (Integer) tag;
} catch (Exception e) {
e.printStackTrace();
}
if (idToApprove != null) {
try {
rc.approvePendingEdit(idToApprove.intValue(), handleApprovedPendingEdit);
} catch (Exception e) {
Toast.makeText(PendingItemDisplay.this, "Error approving pending edit", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
}
private void rejectAll() throws JSONException {
if (allPending.size() != 0) {
int firstIdToReject = (Integer) allPending.get(0).getTag();
RequestGenerator rc = new RequestGenerator();
try {
rc.rejectPendingEdit(firstIdToReject, createRejectionResponseHandlder(key));
} catch (UnsupportedEncodingException e) {
Toast.makeText(PendingItemDisplay.this, "Error rejecting all pending edits", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
public JsonHttpResponseHandler createRejectionResponseHandlder(final String key) {
return new LoggingJsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject plotData) {
try {
processNextId(plotData);
} catch (JSONException e) {
doError();
}
}
protected void processNextId(JSONObject plotData) throws JSONException {
Plot plot = new Plot(plotData);
PendingEditDescription ped = plot.getPendingEditForKey(key);
if (ped == null) {
Intent intent = new Intent();
intent.putExtra("plot", plotData.toString());
setResult(RESULT_OK, intent);
finish();
} else {
int nextIdToReject = ped.getPendingEdits().get(0).getId();
RequestGenerator rc = new RequestGenerator();
try {
rc.rejectPendingEdit(nextIdToReject, createRejectionResponseHandlder(key));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
doError();
}
}
}
@Override
public void failure(Throwable arg0, String arg1) {
doError();
}
protected void doError() {
Toast.makeText(PendingItemDisplay.this, "Error with pending edits", Toast.LENGTH_SHORT).show();
}
};
}
private final JsonHttpResponseHandler handleApprovedPendingEdit = new LoggingJsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject plotData) {
Intent intent = new Intent();
intent.putExtra("plot", plotData.toString());
setResult(RESULT_OK, intent);
finish();
}
@Override
public void failure(Throwable arg0, String arg1) {
Toast.makeText(PendingItemDisplay.this, "Error with pending edits", Toast.LENGTH_SHORT).show();
}
};
public void handleCancelClick(View view) {
setResult(Activity.RESULT_CANCELED);
finish();
}
}