<commit_before>/*
 * Copyright (c) 2020 toastkidjp.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompany this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html.
 */

package jp.toastkid.yobidashi.browser.webview.factory

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.view.ViewGroup
import android.webkit.WebView
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider
import jp.toastkid.lib.BrowserViewModel
import jp.toastkid.lib.preference.PreferenceApplier
import jp.toastkid.yobidashi.browser.webview.AlphaConverter
import jp.toastkid.yobidashi.browser.webview.CustomWebView
import jp.toastkid.yobidashi.browser.webview.WebSettingApplier
import jp.toastkid.yobidashi.browser.webview.dialog.AnchorTypeLongTapDialogFragment
import jp.toastkid.yobidashi.browser.webview.dialog.ElseCaseLongTapDialogFragment
import jp.toastkid.yobidashi.browser.webview.dialog.ImageAnchorTypeLongTapDialogFragment
import jp.toastkid.yobidashi.browser.webview.dialog.ImageTypeLongTapDialogFragment

/**
 * [WebView] factory.
 *
 * @author toastkidjp
 */
internal class WebViewFactory {

    /**
     * Use for only extract anchor URL.
     */
    private val handler = Handler(Looper.getMainLooper()) {
        it.data?.let(longTapItemHolder::extract)
        true
    }

    private val longTapItemHolder = LongTapItemHolder()

    /**
     * Color alpha converter.
     */
    private val alphaConverter = AlphaConverter()

    /**
     * Make new [WebView].
     *
     * @param context [Context]
     * @return [CustomWebView]
     */
    @SuppressLint("ClickableViewAccessibility")
    fun make(context: Context): CustomWebView {
        val webView = CustomWebView(context)
        webView.layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
        )

        val preferenceApplier = PreferenceApplier(context)

        webView.setOnLongClickListener {
            val hitResult = webView.hitTestResult
            when (hitResult.type) {
                WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE -> {
                    val url = hitResult.extra ?: return@setOnLongClickListener false
                    webView.requestFocusNodeHref(handler.obtainMessage())
                    if (context is FragmentActivity) {
                        if (longTapItemHolder.anchor.isEmpty()) {
                            handler.postDelayed({
                                showImageAnchorDialog(url, context)
                                longTapItemHolder.reset()
                            }, 300L)

                            return@setOnLongClickListener true
                        }
                        showImageAnchorDialog(url, context)
                    }
                    false
                }
                WebView.HitTestResult.IMAGE_TYPE -> {
                    val url = hitResult.extra ?: return@setOnLongClickListener false
                    if (context is FragmentActivity) {
                        showDialogFragment(
                                ImageTypeLongTapDialogFragment.make(url),
                                context.supportFragmentManager
                        )
                    }
                    true
                }
                WebView.HitTestResult.SRC_ANCHOR_TYPE -> {
                    webView.requestFocusNodeHref(handler.obtainMessage())

                    if (context is FragmentActivity) {
                        handler.postDelayed(
                                {
                                    showDialogFragment(
                                            AnchorTypeLongTapDialogFragment
                                                    .make(longTapItemHolder.title, longTapItemHolder.anchor),
                                            context.supportFragmentManager
                                    )
                                    longTapItemHolder.reset()
                                },
                                300L
                        )
                        return@setOnLongClickListener true
                    }
                    false
                }
                else -> {
                    val extra = hitResult.extra ?: return@setOnLongClickListener false

                    if (context is FragmentActivity) {
                        ElseCaseLongTapDialogFragment
                                .make(preferenceApplier.getDefaultSearchEngine() ?: jp.toastkid.search.SearchCategory.getDefaultCategoryName(), extra)
                                .show(
                                        context.supportFragmentManager,
                                        ElseCaseLongTapDialogFragment::class.java.simpleName
                                )
                    }
                    false
                }
            }
        }

        WebSettingApplier(preferenceApplier).invoke(webView.settings)

        webView.isNestedScrollingEnabled = true
        webView.setBackgroundColor(alphaConverter.readBackground(context))

        webView.setDownloadListener { url, _, _, mimeType, _ ->
            when {
                mimeType == "application/pdf" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
                    val intent = Intent(Intent.ACTION_QUICK_VIEW)
                    intent.data = Uri.parse(url)
                    webView.context.startActivity(intent)
                }
                else -> {
                    (context as? FragmentActivity)?.let {
                        ViewModelProvider(it).get(BrowserViewModel::class.java).download(url)
                    }
                }
            }
        }

        return webView
    }

    /**
     * Show image anchor type dialog.
     *
     * @param url URL string
     * @param fragmentActivity [FragmentActivity]
     */
    private fun showImageAnchorDialog(url: String, fragmentActivity: FragmentActivity) {
        val dialogFragment = ImageAnchorTypeLongTapDialogFragment.make(
                longTapItemHolder.title,
                url,
                longTapItemHolder.anchor
        )

        showDialogFragment(
                dialogFragment,
                fragmentActivity.supportFragmentManager
        )<commit_msg>feature #231 Enable to open downloaded PDF.<commit_after>/*
 * Copyright (c) 2020 toastkidjp.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompany this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html.
 */

package jp.toastkid.yobidashi.browser.webview.factory

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.view.ViewGroup
import android.webkit.WebView
import androidx.core.net.toUri
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider
import jp.toastkid.lib.BrowserViewModel
import jp.toastkid.lib.preference.PreferenceApplier
import jp.toastkid.yobidashi.browser.webview.AlphaConverter
import jp.toastkid.yobidashi.browser.webview.CustomWebView
import jp.toastkid.yobidashi.browser.webview.WebSettingApplier
import jp.toastkid.yobidashi.browser.webview.dialog.AnchorTypeLongTapDialogFragment
import jp.toastkid.yobidashi.browser.webview.dialog.ElseCaseLongTapDialogFragment
import jp.toastkid.yobidashi.browser.webview.dialog.ImageAnchorTypeLongTapDialogFragment
import jp.toastkid.yobidashi.browser.webview.dialog.ImageTypeLongTapDialogFragment

/**
 * [WebView] factory.
 *
 * @author toastkidjp
 */
internal class WebViewFactory {

    /**
     * Use for only extract anchor URL.
     */
    private val handler = Handler(Looper.getMainLooper()) {
        it.data?.let(longTapItemHolder::extract)
        true
    }

    private val longTapItemHolder = LongTapItemHolder()

    /**
     * Color alpha converter.
     */
    private val alphaConverter = AlphaConverter()

    /**
     * Make new [WebView].
     *
     * @param context [Context]
     * @return [CustomWebView]
     */
    @SuppressLint("ClickableViewAccessibility")
    fun make(context: Context): CustomWebView {
        val webView = CustomWebView(context)
        webView.layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
        )

        val preferenceApplier = PreferenceApplier(context)

        webView.setOnLongClickListener {
            val hitResult = webView.hitTestResult
            when (hitResult.type) {
                WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE -> {
                    val url = hitResult.extra ?: return@setOnLongClickListener false
                    webView.requestFocusNodeHref(handler.obtainMessage())
                    if (context is FragmentActivity) {
                        if (longTapItemHolder.anchor.isEmpty()) {
                            handler.postDelayed({
                                showImageAnchorDialog(url, context)
                                longTapItemHolder.reset()
                            }, 300L)

                            return@setOnLongClickListener true
                        }
                        showImageAnchorDialog(url, context)
                    }
                    false
                }
                WebView.HitTestResult.IMAGE_TYPE -> {
                    val url = hitResult.extra ?: return@setOnLongClickListener false
                    if (context is FragmentActivity) {
                        showDialogFragment(
                                ImageTypeLongTapDialogFragment.make(url),
                                context.supportFragmentManager
                        )
                    }
                    true
                }
                WebView.HitTestResult.SRC_ANCHOR_TYPE -> {
                    webView.requestFocusNodeHref(handler.obtainMessage())

                    if (context is FragmentActivity) {
                        handler.postDelayed(
                                {
                                    showDialogFragment(
                                            AnchorTypeLongTapDialogFragment
                                                    .make(longTapItemHolder.title, longTapItemHolder.anchor),
                                            context.supportFragmentManager
                                    )
                                    longTapItemHolder.reset()
                                },
                                300L
                        )
                        return@setOnLongClickListener true
                    }
                    false
                }
                else -> {
                    val extra = hitResult.extra ?: return@setOnLongClickListener false

                    if (context is FragmentActivity) {
                        ElseCaseLongTapDialogFragment
                                .make(preferenceApplier.getDefaultSearchEngine() ?: jp.toastkid.search.SearchCategory.getDefaultCategoryName(), extra)
                                .show(
                                        context.supportFragmentManager,
                                        ElseCaseLongTapDialogFragment::class.java.simpleName
                                )
                    }
                    false
                }
            }
        }

        WebSettingApplier(preferenceApplier).invoke(webView.settings)

        webView.isNestedScrollingEnabled = true
        webView.setBackgroundColor(alphaConverter.readBackground(context))

        webView.setDownloadListener { url, _, _, mimeType, _ ->
            when {
                mimeType == "application/pdf" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
                    val intent = Intent().also { it.data = url.toUri() }
                    val currentContext = webView.context
                    if (currentContext.packageManager.resolveActivity(intent, 0) == null) {
                        intent.action = Intent.ACTION_VIEW
                    }
                    currentContext.startActivity(intent)
                }
                else -> {
                    (context as? FragmentActivity)?.let {
                        ViewModelProvider(it).get(BrowserViewModel::class.java).download(url)
                    }
                }
            }
        }

        return webView
    }

    /**
     * Show image anchor type dialog.
     *
     * @param url URL string
     * @param fragmentActivity [FragmentActivity]
     */
    private fun showImageAnchorDialog(url: String, fragmentActivity: FragmentActivity) {
        val dialogFragment = ImageAnchorTypeLongTapDialogFragment.make(
                longTapItemHolder.title,
                url,
                longTapItemHolder.anchor
        )

        showDialogFragment(
                dialogFragment,
                fragmentActivity.supportFragmentManager
        )
{'fraction_non_alphanumeric': 0.06883925302087147, 'fraction_numerical': 0.002343463932625412, 'mean_word_length': 1.5530005608524957, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 27, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3960029', 'n_tokens_mistral': 3388, 'n_tokens_neox': 3132, 'n_words': 549}