package org.softeg.slartus.forpdaplus.fragments.search;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.nineoldandroids.view.ViewPropertyAnimator;
import org.softeg.slartus.forpdaapi.search.SearchSettings;
import org.softeg.slartus.forpdacommon.FileUtils;
import org.softeg.slartus.forpdaplus.App;
import org.softeg.slartus.forpdaplus.Client;
import org.softeg.slartus.forpdaplus.IntentActivity;
import org.softeg.slartus.forpdaplus.MainActivity;
import org.softeg.slartus.forpdaplus.R;
import org.softeg.slartus.forpdaplus.classes.AdvWebView;
import org.softeg.slartus.forpdaplus.classes.ForumUser;
import org.softeg.slartus.forpdaplus.classes.SaveHtml;
import org.softeg.slartus.forpdaplus.classes.WebViewExternals;
import org.softeg.slartus.forpdaplus.classes.common.ExtUrl;
import org.softeg.slartus.forpdaplus.common.AppLog;
import org.softeg.slartus.forpdaplus.fragments.WebViewFragment;
import org.softeg.slartus.forpdaplus.prefs.Preferences;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by radiationx on 15.11.15.
*/
public class SearchPostFragment extends WebViewFragment implements ISearchResultView {
private Handler mHandler = new Handler();
private AdvWebView mWvBody;
private static final String SEARCH_URL_KEY = "SEARCH_URL_KEY";
private WebViewExternals m_WebViewExternals;
private Bundle args;
private FrameLayout buttonsPanel;
@Override
public void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
args = getArguments();
}
public static Fragment newFragment(String searchUrl) {
SearchPostFragment fragment = new SearchPostFragment();
Bundle args = new Bundle();
args.putString(SEARCH_URL_KEY, searchUrl);
fragment.setArguments(args);
return fragment;
}
private final static int FILECHOOSER_RESULTCODE = 1;
@JavascriptInterface
public void showChooseCssDialog() {
getMainActivity().runOnUiThread(() -> {
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
// intent.setDataAndType(Uri.parse("file://" + lastSelectDirPath), "file/*");
startActivityForResult(intent, FILECHOOSER_RESULTCODE);
} catch (ActivityNotFoundException ex) {
Toast.makeText(getMainActivity(), R.string.no_app_for_get_file, Toast.LENGTH_LONG).show();
} catch (Exception ex) {
AppLog.e(getMainActivity(), ex);
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == FILECHOOSER_RESULTCODE) {
String attachFilePath = FileUtils.getRealPathFromURI(getMainActivity(), data.getData());
String cssData = FileUtils.readFileText(attachFilePath)
.replace("\\", "\\\\")
.replace("'", "\\'").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "");
if (Build.VERSION.SDK_INT < 19)
mWvBody.loadUrl("javascript:window['HtmlInParseLessContent']('" + cssData + "');");
else
mWvBody.evaluateJavascript("window['HtmlInParseLessContent']('" + cssData + "')",
new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
}
}
);
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//setHideActionBar();
search(0);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.search_posts_result, container, false);
initSwipeRefreshLayout();
assert view != null;
mWvBody = (AdvWebView) findViewById(R.id.body_webview);
findViewById(R.id.btnUp).setOnClickListener(this::onBtnUpClick);
findViewById(R.id.btnDown).setOnClickListener(this::onBtnDownClick);
m_WebViewExternals = new WebViewExternals(this);
m_WebViewExternals.loadPreferences(App.getInstance().getPreferences());
configWebView();
m_WebViewExternals.setWebViewSettings();
mWvBody.getSettings().setLoadWithOverviewMode(false);
mWvBody.getSettings().setUseWideViewPort(true);
mWvBody.getSettings().setDefaultFontSize(Preferences.Topic.getFontSize());
mWvBody.addJavascriptInterface(this, "HTMLOUT");
mWvBody.loadDataWithBaseURL("http://4pda.ru/forum/", "<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">" +
"</head><body bgcolor=" + App.getInstance().getCurrentBackgroundColorHtml() + "></body></html>", "text/html", "UTF-8", null);
registerForContextMenu(mWvBody);
buttonsPanel = (FrameLayout)findViewById(R.id.buttonsPanel);
return view;
}
@Override
public String getResultView() {
return SearchSettings.RESULT_VIEW_POSTS;
}
@Override
public void search(String searchQuery) {
if (args == null)
args = new Bundle();
args.putString(SEARCH_URL_KEY, searchQuery);
search(0);
}
LoadResultTask mTask;
public void search(final int startNum) {
Runnable runnable = () -> {
mTask = new LoadResultTask(startNum);
mTask.execute();
};
if (mTask != null && mTask.getStatus() != AsyncTask.Status.FINISHED)
mTask.cancel(false);
else {
runnable.run();
}
}
public Context getContext() {
return getMainActivity();
}
private void configWebView() {
mWvBody.getSettings().setJavaScriptEnabled(true);
mWvBody.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
mWvBody.getSettings().setDomStorageEnabled(true);
mWvBody.getSettings().setAllowFileAccess(true);
if (App.getInstance().getPreferences().getBoolean("system.WebViewScroll", true)) {
mWvBody.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mWvBody.setScrollbarFadingEnabled(false);
}
m_WebViewExternals.setWebViewSettings();
mWvBody.setWebViewClient(new MyWebViewClient());
mWvBody.addJavascriptInterface(this, "HTMLOUT");
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo, Handler mHandler) {
super.onCreateContextMenu(menu, v, menuInfo);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return m_WebViewExternals.dispatchKeyEvent(event);
}
private void showHtmlBody(String body) {
try {
MainActivity.searchSettings = SearchSettings.parse(getSearchQuery());
mWvBody.loadDataWithBaseURL("http://4pda.ru/forum/", body, "text/html", "UTF-8", null);
if(buttonsPanel.getTranslationY()!=0)
ViewPropertyAnimator.animate(buttonsPanel)
.setInterpolator(new AccelerateDecelerateInterpolator())
.setDuration(500)
.translationY(0);
} catch (Exception ex) {
AppLog.e(getContext(), ex);
}
}
@JavascriptInterface
public void showUserMenu(final String userId, final String userNick) {
getMainActivity().runOnUiThread(() -> ForumUser.showUserQuickAction(getMainActivity(), getWebView(), userId, userNick));
}
@JavascriptInterface
public void nextPage() {
getMainActivity().runOnUiThread(() -> search(m_SearchResult.getCurrentPage() * m_SearchResult.getPostsPerPageCount(getSearchQuery())));
}
private String getSearchQuery() {
return args.getString(SEARCH_URL_KEY);
}
@JavascriptInterface
public void prevPage() {
getMainActivity().runOnUiThread(() -> search((m_SearchResult.getCurrentPage() - 2) * m_SearchResult.getPostsPerPageCount(getSearchQuery())));
}
@JavascriptInterface
public void firstPage() {
getMainActivity().runOnUiThread(() -> search(0));
}
@JavascriptInterface
public void lastPage() {
getMainActivity().runOnUiThread(() -> search((m_SearchResult.getPagesCount() - 1) * m_SearchResult.getPostsPerPageCount(getSearchQuery())));
}
@JavascriptInterface
public void jumpToPage() {
getMainActivity().runOnUiThread(() -> {
CharSequence[] pages = new CharSequence[m_SearchResult.getPagesCount()];
final int postsPerPage;
postsPerPage = m_SearchResult.getPostsPerPageCount(getSearchQuery());
final String page = getContext().getString(R.string.page_short);
for (int p = 0; p < m_SearchResult.getPagesCount(); p++) {
pages[p] = page + (p + 1) + " (" + ((p * postsPerPage + 1) + "-" + (p + 1) * postsPerPage) + ")";
}
new MaterialDialog.Builder(getContext())
.title(R.string.jump_to_page)
.items(pages)
.itemsCallbackSingleChoice(m_SearchResult.getCurrentPage() - 1, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View view1, int i, CharSequence pages) {
search(i * postsPerPage);
return true; // allow selection
}
})
.show();
});
}
public String Prefix() {
return "theme";
}
@Override
@JavascriptInterface
public void saveHtml(final String html) {
getMainActivity().runOnUiThread(() -> new SaveHtml(getMainActivity(), html, "search"));
}
public AdvWebView getWebView() {
return mWvBody;
}
@Override
public WebViewClient getWebViewClient() {
return new MyWebViewClient();
}
@Override
public String getTitle() {
return App.getContext().getString(R.string.search);
}
@Override
public String getUrl() {
return getSearchQuery();
}
@Override
public void reload() {
search(0);
}
@Override
public AsyncTask getAsyncTask() {
return null;
}
@Override
public boolean closeTab() {
return false;
}
public Window getWindow() {
assert getContext() != null;
return ((Activity) getContext()).getWindow();
}
public ActionBar getSupportActionBar() {
return null;
}
public boolean dispatchSuperKeyEvent(KeyEvent event) {
return false;
}
public void onBtnUpClick(View view) {
mWvBody.pageUp(true);
}
public void onBtnDownClick(View view) {
mWvBody.pageDown(true);
}
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, final String url) {
if (url.contains("HTMLOUT.ru")) {
Uri uri = Uri.parse(url);
try {
String function = uri.getPathSegments().get(0);
String query = uri.getQuery();
Class[] parameterTypes = null;
String[] parameterValues = new String[0];
if (!TextUtils.isEmpty(query)) {
Matcher m = Pattern.compile("(.*?)=(.*?)(&|$)").matcher(query);
ArrayList<String> objs = new ArrayList<>();
while (m.find()) {
objs.add(m.group(2));
}
parameterValues = new String[objs.size()];
parameterTypes = new Class[objs.size()];
for (int i = 0; i < objs.size(); i++) {
parameterTypes[i] = String.class;
parameterValues[i] = objs.get(i);
}
}
Method method = this.getClass().getMethod(function, parameterTypes);
method.invoke(getMainActivity(), parameterValues);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
IntentActivity.tryShowUrl((Activity) getContext(), mHandler, url, true, false);
return true;
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.add(R.string.link)
.setOnMenuItemClickListener(menuItem -> {
ExtUrl.showSelectActionDialog(getMainActivity(), getString(R.string.link), getSearchQuery());
return true;
});
}
@Override
public void onPause() {
super.onPause();
MainActivity.searchSettings = SearchSettingsDialogFragment.createDefaultSearchSettings();
}
@Override
public void onResume() {
super.onResume();
MainActivity.searchSettings = SearchSettings.parse(getSearchQuery());
}
private SearchResult m_SearchResult;
private class LoadResultTask extends AsyncTask<String, String, Boolean> {
private int m_Page;
public LoadResultTask(int page) {
m_Page = page;
}
private String pageBody;
@Override
protected Boolean doInBackground(String... params) {
try {
if (this.isCancelled()) return false;
pageBody = Client.getInstance().loadPageAndCheckLogin(getSearchQuery() + "&st=" + m_Page, null);
SearchPostsParser searchPostsParser = new SearchPostsParser();
pageBody = searchPostsParser.parse(pageBody);
m_SearchResult = searchPostsParser.searchResult;
return true;
} catch (Throwable e) {
//Log.e(getContext(), e);
ex = e;
return false;
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
setLoading(true);
}
private Throwable ex;
protected void onCancelled() {
super.onCancelled();
}
protected void onPostExecute(final Boolean success) {
setLoading(false);
showHtmlBody(pageBody);
if (ex != null)
AppLog.e(getContext(), ex);
super.onPostExecute(success);
}
}
}