package com.uservoice.uservoicesdk.ui;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.uservoice.uservoicesdk.R;
import com.uservoice.uservoicesdk.Session;
import com.uservoice.uservoicesdk.deflection.Deflection;
import com.uservoice.uservoicesdk.model.Article;
import com.uservoice.uservoicesdk.model.BaseModel;
import com.uservoice.uservoicesdk.model.Suggestion;
import java.util.ArrayList;
import java.util.List;
public abstract class InstantAnswersAdapter extends BaseAdapter implements ViewGroup.OnHierarchyChangeListener, OnItemClickListener {
protected int TEXT = 0;
protected int BUTTON = 1;
protected int HEADING = 2;
protected int LOADING = 3;
protected int INSTANT_ANSWER = 4;
protected int EMAIL_FIELD = 5;
protected int NAME_FIELD = 6;
protected int SPACE = 7;
protected State state = State.INIT;
protected List<BaseModel> instantAnswers;
protected FragmentActivity context;
protected LayoutInflater inflater;
protected EditText textField;
protected EditText emailField;
protected EditText nameField;
protected int continueButtonMessage;
public InstantAnswersAdapter(FragmentActivity context) {
this.context = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
protected abstract List<Integer> getDetailRows();
protected abstract void doSubmit();
protected abstract String getSubmitString();
@Override
public int getViewTypeCount() {
return 8;
}
protected List<Integer> getRows() {
List<Integer> rows = new ArrayList<Integer>();
rows.add(TEXT);
if (state != State.INIT && state != State.INIT_LOADING && !instantAnswers.isEmpty()) {
rows.add(SPACE);
rows.add(HEADING);
}
if (state == State.INSTANT_ANSWERS || state == State.DETAILS) {
if (instantAnswers.size() > 0)
rows.add(INSTANT_ANSWER);
if (instantAnswers.size() > 1)
rows.add(INSTANT_ANSWER);
if (instantAnswers.size() > 2)
rows.add(INSTANT_ANSWER);
}
if (state == State.DETAILS) {
rows.add(SPACE);
rows.addAll(getDetailRows());
}
rows.add(BUTTON);
return rows;
}
protected boolean isLoading() {
return Session.getInstance().getClientConfig() == null;
}
@Override
public int getCount() {
return isLoading() ? 1 : getRows().size();
}
@Override
public int getItemViewType(int position) {
return isLoading() ? LOADING : getRows().get(position);
}
public void notHelpful() {
if (state == State.INSTANT_ANSWERS) {
state = State.DETAILS;
notifyDataSetChanged();
}
}
@Override
public boolean isEnabled(int position) {
int type = getItemViewType(position);
return type == INSTANT_ANSWER;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int type = getItemViewType(position);
if (type == INSTANT_ANSWER) {
Deflection.trackDeflection("show", (BaseModel) getItem(position));
Utils.showModel(context, (BaseModel) getItem(position));
}
}
@Override
public void onChildViewAdded(View parent, View child) {
if (state == State.DETAILS && emailField != null)
emailField.requestFocus();
else if (textField != null)
textField.requestFocus();
}
@Override
public void onChildViewRemoved(View parent, View child) {
onChildViewAdded(null, null);
}
@SuppressLint("CutPasteId")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
int type = getItemViewType(position);
if (view == null) {
if (type == LOADING) {
view = inflater.inflate(R.layout.uv_loading_item, null);
} else if (type == BUTTON) {
view = inflater.inflate(R.layout.uv_contact_button_item, null);
Button button = (Button) view.findViewById(R.id.uv_contact_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onButtonTapped();
}
});
} else if (type == HEADING) {
view = inflater.inflate(R.layout.uv_header_item, null);
} else if (type == INSTANT_ANSWER) {
view = inflater.inflate(R.layout.uv_instant_answer_item, null);
} else if (type == SPACE) {
view = new LinearLayout(context);
view.setPadding(0, 30, 0, 0);
} else if (type == TEXT) {
view = inflater.inflate(R.layout.uv_contact_text_item, null);
textField = (EditText) view.findViewById(R.id.uv_text);
textField.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (state != State.INIT) {
state = State.INIT;
notifyDataSetChanged();
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
} else if (type == EMAIL_FIELD || type == NAME_FIELD) {
view = inflater.inflate(R.layout.uv_text_field_item, null);
}
}
if (type == BUTTON) {
Button button = (Button) view.findViewById(R.id.uv_contact_button);
button.setEnabled(state != State.INIT_LOADING);
switch (state) {
case INIT:
button.setText(R.string.uv_next);
break;
case INIT_LOADING:
button.setText(R.string.uv_loading);
break;
case INSTANT_ANSWERS:
button.setText(continueButtonMessage);
break;
case DETAILS:
button.setText(getSubmitString());
break;
}
} else if (type == INSTANT_ANSWER) {
Utils.displayInstantAnswer(view, (BaseModel) getItem(position));
view.findViewById(R.id.uv_divider).setVisibility(getRows().lastIndexOf(INSTANT_ANSWER) == position ? View.GONE : View.VISIBLE);
} else if (type == EMAIL_FIELD || type == NAME_FIELD) {
TextView title = (TextView) view.findViewById(R.id.uv_header_text);
final EditText field = (EditText) view.findViewById(R.id.uv_text_field);
if (type == EMAIL_FIELD) {
title.setText(R.string.uv_your_email_address);
emailField = field;
field.setHint(R.string.uv_email_address_hint);
field.setInputType(EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
field.setText(Session.getInstance().getEmail());
} else if (type == NAME_FIELD) {
title.setText(R.string.uv_your_name);
nameField = field;
field.setHint(R.string.uv_name_hint);
field.setInputType(EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME);
field.setText(Session.getInstance().getName());
}
} else if (type == HEADING) {
TextView textView = (TextView) view.findViewById(R.id.uv_header_text);
boolean hasArticles = false;
boolean hasIdeas = false;
for (BaseModel model : instantAnswers) {
if (model instanceof Article)
hasArticles = true;
if (model instanceof Suggestion)
hasIdeas = true;
}
textView.setText(hasArticles ? (hasIdeas ? R.string.uv_matching_articles_and_ideas : R.string.uv_matching_articles) : R.string.uv_matching_ideas);
}
return view;
}
@Override
public Object getItem(int position) {
int type = getItemViewType(position);
if (type == INSTANT_ANSWER) {
return instantAnswers.get(position - getRows().indexOf(INSTANT_ANSWER));
}
return null;
}
protected void onButtonTapped() {
if (state == State.INIT) {
String query = textField.getText().toString().trim();
if (query.length() == 0)
return;
state = State.INIT_LOADING;
notifyDataSetChanged();
Deflection.setSearchText(query);
Article.loadInstantAnswers(query, new DefaultCallback<List<BaseModel>>(context) {
@Override
public void onModel(List<BaseModel> model) {
Deflection.trackSearchDeflection(model);
instantAnswers = model;
if (instantAnswers.isEmpty())
state = State.DETAILS;
else
state = State.INSTANT_ANSWERS;
notifyDataSetChanged();
}
});
} else if (state == State.INSTANT_ANSWERS) {
state = State.DETAILS;
notifyDataSetChanged();
} else if (state == State.DETAILS) {
String name = nameField.getText().toString();
String email = emailField.getText().toString();
if (email.isEmpty()) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.uv_error);
builder.setMessage(R.string.uv_msg_user_identity_validation);
builder.create().show();
} else {
Session.getInstance().persistIdentity(name, email);
doSubmit();
}
}
}
@Override
public long getItemId(int position) {
return position;
}
public boolean hasText() {
return textField != null && textField.getText().toString().length() != 0;
}
protected enum State {
INIT, INIT_LOADING, INSTANT_ANSWERS, DETAILS
}
}