package fr.neamar.kiss.result;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.support.annotation.MenuRes;
import android.text.Html;
import android.text.Spanned;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
import android.widget.Toast;
import fr.neamar.kiss.KissApplication;
import fr.neamar.kiss.MainActivity;
import fr.neamar.kiss.R;
import fr.neamar.kiss.UiTweaks;
import fr.neamar.kiss.adapter.RecordAdapter;
import fr.neamar.kiss.db.DBHelper;
import fr.neamar.kiss.pojo.AppPojo;
import fr.neamar.kiss.pojo.ContactsPojo;
import fr.neamar.kiss.pojo.PhonePojo;
import fr.neamar.kiss.pojo.Pojo;
import fr.neamar.kiss.pojo.SearchPojo;
import fr.neamar.kiss.pojo.SettingsPojo;
import fr.neamar.kiss.pojo.ShortcutsPojo;
import fr.neamar.kiss.pojo.TogglesPojo;
import fr.neamar.kiss.searcher.QueryInterface;
public abstract class Result {
/**
* Current information pojo
*/
Pojo pojo = null;
public static Result fromPojo(QueryInterface parent, Pojo pojo) {
if (pojo instanceof AppPojo)
return new AppResult((AppPojo) pojo);
else if (pojo instanceof ContactsPojo)
return new ContactsResult(parent, (ContactsPojo) pojo);
else if (pojo instanceof SearchPojo)
return new SearchResult((SearchPojo) pojo);
else if (pojo instanceof SettingsPojo)
return new SettingsResult((SettingsPojo) pojo);
else if (pojo instanceof TogglesPojo)
return new TogglesResult((TogglesPojo) pojo);
else if (pojo instanceof PhonePojo)
return new PhoneResult((PhonePojo) pojo);
else if (pojo instanceof ShortcutsPojo)
return new ShortcutsResult((ShortcutsPojo) pojo);
throw new RuntimeException("Unable to create a result from POJO");
}
/**
* How to display this record ?
*
* @param context android context
* @param convertView a view to be recycled
* @return a view to display as item
*/
public abstract View display(Context context, int position, View convertView);
/**
* How to display the popup menu
*
* @return a PopupMenu object
*/
public PopupMenu getPopupMenu(final Context context, final RecordAdapter parent, View parentView) {
PopupMenu menu = buildPopupMenu(context, parent, parentView);
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
return popupMenuClickHandler(context, parent, item);
}
});
return menu;
}
/**
* Default popup menu implementation, can be overridden by children class to display a more specific menu
*
* @return an inflated, listener-free PopupMenu
*/
PopupMenu buildPopupMenu(Context context, final RecordAdapter parent, View parentView) {
return inflatePopupMenu(R.menu.menu_item_default, context, parentView);
}
protected PopupMenu inflatePopupMenu(@MenuRes int menuId, Context context, View parentView) {
PopupMenu menu = new PopupMenu(context, parentView);
menu.getMenuInflater().inflate(menuId, menu.getMenu());
// If app already pinned, do not display the "add to favorite" option
// otherwise don't show the "remove favorite button"
String favApps = PreferenceManager.getDefaultSharedPreferences(context).
getString("favorite-apps-list", "");
if (favApps.contains(this.pojo.id + ";")) {
menu.getMenu().removeItem(R.id.item_favorites_add);
} else {
menu.getMenu().removeItem(R.id.item_favorites_remove);
}
return menu;
}
/**
* Handler for popup menu action.
* Default implementation only handle remove from history action.
*
* @return Works in the same way as onOptionsItemSelected, return true if the action has been handled, false otherwise
*/
Boolean popupMenuClickHandler(Context context, RecordAdapter parent, MenuItem item) {
switch (item.getItemId()) {
case R.id.item_remove:
removeItem(context, parent);
return true;
case R.id.item_favorites_add:
launchAddToFavorites(context, pojo);
break;
case R.id.item_favorites_remove:
launchRemoveFromFavorites(context, pojo);
break;
}
//Update Search to reflect favorite add, if the "exclude favorites" option is active
((MainActivity) context).updateRecords();
return false;
}
private void launchAddToFavorites(Context context, Pojo app) {
String msg = context.getResources().getString(R.string.toast_favorites_added);
KissApplication.getDataHandler(context).addToFavorites((MainActivity) context, app.id);
Toast.makeText(context, String.format(msg, app.name), Toast.LENGTH_SHORT).show();
}
private void launchRemoveFromFavorites(Context context, Pojo app) {
String msg = context.getResources().getString(R.string.toast_favorites_removed);
KissApplication.getDataHandler(context).removeFromFavorites((MainActivity) context, app.id);
Toast.makeText(context, String.format(msg, app.name), Toast.LENGTH_SHORT).show();
}
/**
* Remove the current result from the list
*
* @param context android context
* @param parent adapter on which to remove the item
*/
private void removeItem(Context context, RecordAdapter parent) {
Toast.makeText(context, R.string.removed_item, Toast.LENGTH_SHORT).show();
parent.removeResult(this);
}
public final void launch(Context context, View v) {
Log.i("log", "Launching " + pojo.id);
recordLaunch(context);
// Launch
doLaunch(context, v);
}
/**
* How to launch this record ? Most probably, will fire an intent. This
* function must call recordLaunch()
*
* @param context android context
*/
protected abstract void doLaunch(Context context, View v);
/**
* How to launch this record "quickly" ? Most probably, same as doLaunch().
* Override to define another behavior.
*
* @param context android context
*/
public void fastLaunch(Context context, View v) {
this.launch(context, v);
}
/**
* Return the icon for this Result, or null if non existing.
*
* @param context android context
*/
public Drawable getDrawable(Context context) {
return null;
}
/**
* Helper function to get a view
*
* @param context android context
* @param id id to inflate
* @return the view specified by the id
*/
View inflateFromId(Context context, int id) {
LayoutInflater vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return vi.inflate(id, null);
}
/**
* Enrich text for display. Put text requiring highlighting between {}
*
* @param text to highlight
* @return text displayable on a textview
*/
Spanned enrichText(String text, Context context) {
return Html.fromHtml(text.replaceAll("\\{", "<font color=" + UiTweaks.getPrimaryColor(context) + ">").replaceAll("\\}", "</font>"));
}
/**
* Put this item in application history
*
* @param context android context
*/
void recordLaunch(Context context) {
// Save in history
KissApplication.getDataHandler(context).addToHistory(pojo.id);
}
public void deleteRecord(Context context) {
DBHelper.removeFromHistory(context, pojo.id);
}
/*
* Get fill color from theme
*
*/
public int getThemeFillColor(Context context) {
int[] attrs = new int[]{R.attr.resultColor /* index 0 */};
TypedArray ta = context.obtainStyledAttributes(attrs);
int color = ta.getColor(0, Color.WHITE);
ta.recycle();
return color;
}
}