/*
* Overchan Android (Meta Imageboard Client)
* Copyright (C) 2014-2016 miku-nyan <https://github.com/miku-nyan>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nya.miku.wishmaster.ui;
import java.util.Calendar;
import java.util.LinkedList;
import nya.miku.wishmaster.R;
import nya.miku.wishmaster.api.ChanModule;
import nya.miku.wishmaster.api.models.UrlPageModel;
import nya.miku.wishmaster.common.MainApplication;
import nya.miku.wishmaster.ui.tabs.TabModel;
import nya.miku.wishmaster.ui.tabs.UrlHandler;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class HistoryFragment extends Fragment implements AdapterView.OnItemClickListener {
private MainActivity activity;
private HistoryAdapter adapter;
private ListView listView;
private static LinkedList<Database.HistoryEntry> lastClosed = new LinkedList<>();
public static void setLastClosed(TabModel tab) {
if (tab != null && tab.pageModel != null) {
switch (tab.pageModel.type) {
case UrlPageModel.TYPE_INDEXPAGE:
lastClosed.add(new Database.HistoryEntry(tab.pageModel.chanName, null, null, null, tab.title, tab.webUrl, 0));
break;
case UrlPageModel.TYPE_BOARDPAGE:
lastClosed.add(new Database.HistoryEntry(tab.pageModel.chanName, tab.pageModel.boardName,
Integer.toString(tab.pageModel.boardPage), null, tab.title, tab.webUrl, 0));
break;
case UrlPageModel.TYPE_THREADPAGE:
lastClosed.add(new Database.HistoryEntry(tab.pageModel.chanName, tab.pageModel.boardName,
null, tab.pageModel.threadNumber, tab.title, tab.webUrl, 0));
break;
}
if (MainApplication.getInstance().tabsSwitcher.currentFragment instanceof HistoryFragment) {
((HistoryFragment) MainApplication.getInstance().tabsSwitcher.currentFragment).init();
}
if (lastClosed.size() > 30) lastClosed.removeFirst();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = (MainActivity) getActivity();
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
activity.setTitle(R.string.tabs_history);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) CompatibilityImpl.setActionBarDefaultIcon(activity);
listView = (ListView) inflater.inflate(R.layout.history_fragment, container, false);
listView.setOnItemClickListener(this);
registerForContextMenu(listView);
init();
return listView;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (adapter == null) return;
Object item = adapter.getItem(position);
if (item instanceof Database.HistoryEntry) {
if (((Database.HistoryEntry) item).date == 0) lastClosed.removeLast();
UrlHandler.open(((Database.HistoryEntry) item).url, activity);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.add(Menu.NONE, R.id.menu_clear_history, 101, R.string.menu_clear_history).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_clear_history) {
if (adapter != null) {
MainApplication.getInstance().database.clearHistory();
lastClosed = new LinkedList<>();
init();
}
return true;
}
return false;
}
private void init() {
adapter = new HistoryAdapter(activity);
listView.setAdapter(adapter);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (adapter == null) return;
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
Object item = adapter.getItem(info.position);
if (item instanceof Database.HistoryEntry) {
Database.HistoryEntry entry = (Database.HistoryEntry) item;
if (entry.date != 0) {
menu.add(Menu.NONE, R.id.context_menu_remove_history, 1, R.string.context_menu_remove_history);
menu.add(Menu.NONE, R.id.context_menu_open_browser, 2, R.string.context_menu_open_browser);
menu.add(Menu.NONE, R.id.context_menu_favorites_from_fragment, 3,
MainApplication.getInstance().database.isFavorite(entry.chan, entry.board, entry.boardPage, entry.thread) ?
R.string.context_menu_remove_favorites : R.string.context_menu_add_favorites);
}
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
int position = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).position;
Object listItem = adapter.getItem(position);
if (listItem instanceof Database.HistoryEntry) {
Database database = MainApplication.getInstance().database;
Database.HistoryEntry entry = (Database.HistoryEntry) listItem;
switch (item.getItemId()) {
case R.id.context_menu_remove_history:
database.removeHistory(entry.chan, entry.board, entry.boardPage, entry.thread);
adapter.remove(entry);
break;
case R.id.context_menu_open_browser:
UrlHandler.launchExternalBrowser(activity, entry.url);
break;
case R.id.context_menu_favorites_from_fragment:
if (database.isFavorite(entry.chan, entry.board, entry.boardPage, entry.thread)) {
database.removeFavorite(entry.chan, entry.board, entry.boardPage, entry.thread);
} else {
database.addFavorite(entry.chan, entry.board, entry.boardPage, entry.thread, entry.title, entry.url);
}
}
return true;
}
return false;
}
private static class HistoryAdapter extends ArrayAdapter<Object> {
private static final int SEPARATOR = 0;
private static final int NORMAL_ITEM = 1;
private LayoutInflater inflater;
private int drawablePadding;
public HistoryAdapter(MainActivity activity) {
super(activity, 0);
Resources resources = activity.getResources();
inflater = LayoutInflater.from(activity);
drawablePadding = (int) (resources.getDisplayMetrics().density * 5 + 0.5f);
long midnight = getMidnight();
int current = 0;
int previous = -1;
if (lastClosed.size() > 0) {
add(resources.getString(R.string.history_last_closed));
add(lastClosed.getLast());
}
for (Database.HistoryEntry entity : MainApplication.getInstance().database.getHistory()) {
while (entity.date < midnight) {
if (current == 0) {
current = 1;
midnight -= 86400 * 1000;
} else if (current == 1) {
current = 2;
midnight -= 86400 * 1000 * 6;
} else {
current = 3;
midnight = 0;
}
}
if (previous != current) {
switch (current) {
case 0:
add(resources.getString(R.string.history_today));
break;
case 1:
add(resources.getString(R.string.history_yesterday));
break;
case 2:
add(resources.getString(R.string.history_last_week));
break;
case 3:
add(resources.getString(R.string.history_other));
break;
}
previous = current;
}
add(entity);
}
if (getCount() == 0) add(resources.getString(R.string.history_empty));
}
private long getMidnight() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTimeInMillis();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Object item = getItem(position);
View v;
if (item instanceof Database.HistoryEntry) {
v = convertView == null ? inflater.inflate(android.R.layout.simple_list_item_2, parent, false) : convertView;
TextView tv1 = (TextView) v.findViewById(android.R.id.text1);
TextView tv2 = (TextView) v.findViewById(android.R.id.text2);
tv1.setSingleLine();
tv2.setSingleLine();
tv1.setEllipsize(TextUtils.TruncateAt.END);
tv2.setEllipsize(TextUtils.TruncateAt.START);
tv1.setText(((Database.HistoryEntry) item).title);
tv2.setText(((Database.HistoryEntry) item).url);
ChanModule chan = MainApplication.getInstance().getChanModule(((Database.HistoryEntry) item).chan);
if (chan != null) {
tv1.setCompoundDrawablesWithIntrinsicBounds(chan.getChanFavicon(), null, null, null);
tv1.setCompoundDrawablePadding(drawablePadding);
}
} else {
v = convertView == null ? inflater.inflate(R.layout.list_separator, parent, false) : convertView;
TextView tv = (TextView) v;
tv.setText((String) item);
}
return v;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
return getItem(position) instanceof Database.HistoryEntry ? NORMAL_ITEM : SEPARATOR;
}
}
}